X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fgsettings.c;h=23a14bcc90db2540da6dd8c182aa62a172f7dc27;hb=a3d86afa81ff34ce797a3928fd619ead219a37af;hp=dca65d90fe24ef11ee6e4038e031ad78571b9afd;hpb=bebdfb8e6264f61ffefce3ce297f860909ee2ea3;p=platform%2Fupstream%2Fglib.git diff --git a/gio/gsettings.c b/gio/gsettings.c index dca65d9..23a14bc 100644 --- a/gio/gsettings.c +++ b/gio/gsettings.c @@ -12,9 +12,7 @@ * 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, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library; if not, see . * * Author: Ryan Lortie */ @@ -38,6 +36,7 @@ /** * SECTION:gsettings * @short_description: High-level API for application settings + * @include: gio/gio.h * * The #GSettings class provides a convenient API for storing and retrieving * application settings. @@ -84,43 +83,52 @@ * the names must begin with a lowercase character, must not end * with a '-', and must not contain consecutive dashes. * + * GSettings supports change notification. The primary mechanism to + * watch for changes is to connect to the "changed" signal. You can + * optionally watch for changes on only a single key by using a signal + * detail. Signals are only guaranteed to be emitted for a given key + * after you have read the value of that key while a signal handler was + * connected for that key. Signals may or may not be emitted in the + * case that the key "changed" to the value that you had previously + * read. Signals may be reported in additional cases as well and the + * "changed" signal should really be treated as "may have changed". + * * Similar to GConf, the default values in GSettings schemas can be * localized, but the localized values are stored in gettext catalogs * and looked up with the domain that is specified in the - * gettext-domain attribute of the - * schemalist or schema - * elements and the category that is specified in the l10n attribute of the - * key element. + * gettext-domain attribute of the or + * elements and the category that is specified in the l10n attribute of + * the element. * * GSettings uses schemas in a compact binary form that is created - * by the glib-compile-schemas - * utility. The input is a schema description in an XML format that can be - * described by the following DTD: - * |[FIXME: MISSING XINCLUDE CONTENT]| - * - * glib-compile-schemas expects schema files to have the extension .gschema.xml - * - * At runtime, schemas are identified by their id (as specified - * in the id attribute of the - * schema element). The - * convention for schema ids is to use a dotted name, similar in - * style to a D-Bus bus name, e.g. "org.gnome.SessionManager". In particular, - * if the settings are for a specific service that owns a D-Bus bus name, - * the D-Bus bus name and schema id should match. For schemas which deal - * with settings not associated with one named application, the id should - * not use StudlyCaps, e.g. "org.gnome.font-rendering". - * - * In addition to #GVariant types, keys can have types that have enumerated - * types. These can be described by a choice, - * enum or flags element, see - * . The underlying type of - * such a key is string, but you can use g_settings_get_enum(), - * g_settings_set_enum(), g_settings_get_flags(), g_settings_set_flags() - * access the numeric values corresponding to the string value of enum - * and flags keys. - * - * Default values - * element). The convention for schema + * ids is to use a dotted name, similar in style to a D-Bus bus name, + * e.g. "org.gnome.SessionManager". In particular, if the settings are + * for a specific service that owns a D-Bus bus name, the D-Bus bus name + * and schema id should match. For schemas which deal with settings not + * associated with one named application, the id should not use + * StudlyCaps, e.g. "org.gnome.font-rendering". + * + * In addition to #GVariant types, keys can have types that have + * enumerated types. These can be described by a , + * or element, as seen in the + * [example][schema-enumerated]. The underlying type of such a key + * is string, but you can use g_settings_get_enum(), g_settings_set_enum(), + * g_settings_get_flags(), g_settings_set_flags() access the numeric values + * corresponding to the string value of enum and flags keys. + * + * An example for default value: + * |[ * * * @@ -138,10 +146,10 @@ * * * - * ]]> + * ]| * - * Ranges, choices and enumerated types - * * * @@ -184,52 +192,43 @@ * * * - * ]]> - * - * - * Vendor overrides - * - * Default values are defined in the schemas that get installed by - * an application. Sometimes, it is necessary for a vendor or distributor - * to adjust these defaults. Since patching the XML source for the schema - * is inconvenient and error-prone, - * glib-compile-schemas reads - * so-called 'vendor override' files. These are keyfiles in the same - * directory as the XML schema sources which can override default values. - * The schema id serves as the group name in the key file, and the values - * are expected in serialized GVariant form, as in the following example: - * + * ]| + * + * ## Vendor overrides + * + * Default values are defined in the schemas that get installed by + * an application. Sometimes, it is necessary for a vendor or distributor + * to adjust these defaults. Since patching the XML source for the schema + * is inconvenient and error-prone, + * [glib-compile-schemas][glib-compile-schemas] reads so-called vendor + * override' files. These are keyfiles in the same directory as the XML + * schema sources which can override default values. The schema id serves + * as the group name in the key file, and the values are expected in + * serialized GVariant form, as in the following example: + * |[ * [org.gtk.Example] * key1='string' * key2=1.5 - * - * - * - * glib-compile-schemas expects schema files to have the extension - * .gschema.override - * - * - * - * - * Binding - * - * A very convenient feature of GSettings lets you bind #GObject properties - * directly to settings, using g_settings_bind(). Once a GObject property - * has been bound to a setting, changes on either side are automatically - * propagated to the other side. GSettings handles details like - * mapping between GObject and GVariant types, and preventing infinite - * cycles. - * - * - * This makes it very easy to hook up a preferences dialog to the - * underlying settings. To make this even more convenient, GSettings - * looks for a boolean property with the name "sensitivity" and - * automatically binds it to the writability of the bound setting. - * If this 'magic' gets in the way, it can be suppressed with the - * #G_SETTINGS_BIND_NO_SENSITIVITY flag. - * - * - **/ + * ]| + * + * glib-compile-schemas expects schema files to have the extension + * `.gschema.override`. + * + * ## Binding + * + * A very convenient feature of GSettings lets you bind #GObject properties + * directly to settings, using g_settings_bind(). Once a GObject property + * has been bound to a setting, changes on either side are automatically + * propagated to the other side. GSettings handles details like mapping + * between GObject and GVariant types, and preventing infinite cycles. + * + * This makes it very easy to hook up a preferences dialog to the + * underlying settings. To make this even more convenient, GSettings + * looks for a boolean property with the name "sensitivity" and + * automatically binds it to the writability of the bound setting. + * If this 'magic' gets in the way, it can be suppressed with the + * #G_SETTINGS_BIND_NO_SENSITIVITY flag. + */ struct _GSettingsPrivate { @@ -240,6 +239,8 @@ struct _GSettingsPrivate GSettingsSchema *schema; gchar *path; + gboolean is_subscribed; + GDelayedSettingsBackend *delayed; }; @@ -315,6 +316,32 @@ g_settings_real_writable_change_event (GSettings *settings, return FALSE; } +static gboolean +g_settings_has_signal_handlers (GSettings *settings, + const gchar *key) +{ + GSettingsClass *class = G_SETTINGS_GET_CLASS (settings); + GQuark keyq; + + if (class->change_event != g_settings_real_change_event || + class->writable_change_event != g_settings_real_writable_change_event) + return TRUE; + + keyq = g_quark_from_string (key); + + if (g_signal_has_handler_pending (settings, g_settings_signals[SIGNAL_WRITABLE_CHANGE_EVENT], 0, TRUE) || + g_signal_has_handler_pending (settings, g_settings_signals[SIGNAL_WRITABLE_CHANGED], 0, TRUE) || + g_signal_has_handler_pending (settings, g_settings_signals[SIGNAL_WRITABLE_CHANGED], keyq, TRUE) || + g_signal_has_handler_pending (settings, g_settings_signals[SIGNAL_CHANGE_EVENT], 0, TRUE) || + g_signal_has_handler_pending (settings, g_settings_signals[SIGNAL_CHANGED], 0, TRUE) || + g_signal_has_handler_pending (settings, g_settings_signals[SIGNAL_CHANGED], keyq, TRUE)) + return TRUE; + + /* None of that? Then surely nobody is watching.... */ + return FALSE; +} + + static void settings_backend_changed (GObject *target, GSettingsBackend *backend, @@ -368,8 +395,8 @@ static void settings_backend_keys_changed (GObject *target, GSettingsBackend *backend, const gchar *path, - const gchar * const *items, - gpointer origin_tag) + gpointer origin_tag, + const gchar * const *items) { GSettings *settings = G_SETTINGS (target); gboolean ignore_this; @@ -581,8 +608,6 @@ g_settings_constructed (GObject *object) g_settings_backend_watch (settings->priv->backend, &listener_vtable, G_OBJECT (settings), settings->priv->main_context); - g_settings_backend_subscribe (settings->priv->backend, - settings->priv->path); } static void @@ -590,8 +615,10 @@ g_settings_finalize (GObject *object) { GSettings *settings = G_SETTINGS (object); - g_settings_backend_unsubscribe (settings->priv->backend, - settings->priv->path); + if (settings->priv->is_subscribed) + g_settings_backend_unsubscribe (settings->priv->backend, + settings->priv->path); + g_main_context_unref (settings->priv->main_context); g_object_unref (settings->priv->backend); g_settings_schema_unref (settings->priv->schema); @@ -644,7 +671,7 @@ g_settings_class_init (GSettingsClass *class) * GSettings::change-event: * @settings: the object on which the signal was emitted * @keys: (array length=n_keys) (element-type GQuark) (allow-none): - * an array of #GQuarks for the changed keys, or %NULL + * an array of #GQuarks for the changed keys, or %NULL * @n_keys: the length of the @keys array, or 0 * * The "change-event" signal is emitted once per change event that @@ -1056,6 +1083,13 @@ g_settings_read_from_backend (GSettings *settings, GVariant *fixup; gchar *path; + /* If we are not yet watching for changes, consider doing it now... */ + if (!settings->priv->is_subscribed && g_settings_has_signal_handlers (settings, key->name)) + { + g_settings_backend_subscribe (settings->priv->backend, settings->priv->path); + settings->priv->is_subscribed = TRUE; + } + path = g_strconcat (settings->priv->path, key->name, NULL); if (user_value_only) value = g_settings_backend_read_user_value (settings->priv->backend, path, key->type); @@ -1116,7 +1150,7 @@ g_settings_get_value (GSettings *settings, /** * g_settings_get_user_value: * @settings: a #GSettings object - * @key: the key to check for being set + * @key: the key to get the user value for * * Checks the "user value" of a key, if there is one. * @@ -1137,7 +1171,7 @@ g_settings_get_value (GSettings *settings, * It is a programmer error to give a @key that isn't contained in the * schema for @settings. * - * Returns: (allow none) (transfer full): the user's value, if set + * Returns: (allow-none) (transfer full): the user's value, if set * * Since: 2.40 **/ @@ -1161,7 +1195,7 @@ g_settings_get_user_value (GSettings *settings, /** * g_settings_get_default_value: * @settings: a #GSettings object - * @key: the key to check for being set + * @key: the key to get the default value for * * Gets the "default value" of a key. * @@ -1185,7 +1219,7 @@ g_settings_get_user_value (GSettings *settings, * It is a programmer error to give a @key that isn't contained in the * schema for @settings. * - * Returns: (allow none) (transfer full): the default value + * Returns: (allow-none) (transfer full): the default value * * Since: 2.40 **/ @@ -1528,6 +1562,13 @@ g_settings_get (GSettings *settings, value = g_settings_get_value (settings, key); + if (strchr (format, '&')) + { + g_critical ("%s: the format string may not contain '&' (key '%s' from schema '%s'). " + "This call will probably stop working with a future version of glib.", + G_STRFUNC, key, g_settings_schema_get_id (settings->priv->schema)); + } + va_start (ap, format); g_variant_get_va (value, format, NULL, &ap); va_end (ap); @@ -2175,14 +2216,14 @@ g_settings_is_writable (GSettings *settings, /** * g_settings_get_child: * @settings: a #GSettings object - * @name: the name of the 'child' schema + * @name: the name of the child schema * - * Creates a 'child' settings object which has a base path of - * base-path/@name, where - * base-path is the base path of @settings. + * Creates a child settings object which has a base path of + * `base-path/@name`, where `base-path` is the base path of + * @settings. * * The schema for the child settings object must have been declared - * in the schema of @settings using a child element. + * in the schema of @settings using a element. * * Returns: (transfer full): a 'child' settings object * @@ -2208,6 +2249,7 @@ g_settings_get_child (GSettings *settings, child_path = g_strconcat (settings->priv->path, child_name, NULL); child = g_object_new (G_TYPE_SETTINGS, + "backend", settings->priv->backend, "schema-id", child_schema, "path", child_path, NULL); @@ -2315,80 +2357,22 @@ g_settings_list_children (GSettings *settings) * * Queries the range of a key. * - * This function will return a #GVariant that fully describes the range - * of values that are valid for @key. - * - * The type of #GVariant returned is (sv). The - * string describes the type of range restriction in effect. The type - * and meaning of the value contained in the variant depends on the - * string. - * - * If the string is 'type' then the variant contains - * an empty array. The element type of that empty array is the expected - * type of value and all values of that type are valid. - * - * If the string is 'enum' then the variant contains - * an array enumerating the possible values. Each item in the array is - * a possible valid value and no other values are valid. - * - * If the string is 'flags' then the variant contains - * an array. Each item in the array is a value that may appear zero or - * one times in an array to be used as the value for this key. For - * example, if the variant contained the array ['x', - * 'y'] then the valid values for the key would be - * [], ['x'], - * ['y'], ['x', 'y'] and - * ['y', 'x']. - * - * Finally, if the string is 'range' then the variant - * contains a pair of like-typed values -- the minimum and maximum - * permissible values for this key. - * - * This information should not be used by normal programs. It is - * considered to be a hint for introspection purposes. Normal programs - * should already know what is permitted by their own schema. The - * format may change in any way in the future -- but particularly, new - * forms may be added to the possibilities described above. - * - * It is a programmer error to give a @key that isn't contained in the - * schema for @settings. - * - * You should free the returned value with g_variant_unref() when it is - * no longer needed. - * - * Returns: a #GVariant describing the range - * * Since: 2.28 + * + * Deprecated:2.40:Use g_settings_schema_key_get_range() instead. **/ GVariant * g_settings_get_range (GSettings *settings, const gchar *key) { GSettingsSchemaKey skey; - const gchar *type; GVariant *range; g_settings_schema_key_init (&skey, settings->priv->schema, key); - - if (skey.minimum) - { - range = g_variant_new ("(**)", skey.minimum, skey.maximum); - type = "range"; - } - else if (skey.strinfo) - { - range = strinfo_enumerate (skey.strinfo, skey.strinfo_length); - type = skey.is_flags ? "flags" : "enum"; - } - else - { - range = g_variant_new_array (skey.type, NULL, 0); - type = "type"; - } - + range = g_settings_schema_key_get_range (&skey); g_settings_schema_key_clear (&skey); - return g_variant_ref_sink (g_variant_new ("(sv)", type, range)); + return range; } /** @@ -2400,16 +2384,11 @@ g_settings_get_range (GSettings *settings, * Checks if the given @value is of the correct type and within the * permitted range for @key. * - * This API is not intended to be used by normal programs -- they should - * already know what is permitted by their own schemas. This API is - * meant to be used by programs such as editors or commandline tools. - * - * It is a programmer error to give a @key that isn't contained in the - * schema for @settings. - * * Returns: %TRUE if @value is valid for @key * * Since: 2.28 + * + * Deprecated:2.40:Use g_settings_schema_key_range_check() instead. **/ gboolean g_settings_range_check (GSettings *settings, @@ -2420,8 +2399,7 @@ g_settings_range_check (GSettings *settings, gboolean good; g_settings_schema_key_init (&skey, settings->priv->schema, key); - good = g_settings_schema_key_type_check (&skey, value) && - g_settings_schema_key_range_check (&skey, value); + good = g_settings_schema_key_range_check (&skey, value); g_settings_schema_key_clear (&skey); return good; @@ -2907,8 +2885,7 @@ g_settings_binding_writable_changed (GSettings *settings, * * When the @inverted argument is %TRUE, the binding inverts the * value as it passes from the setting to the object, i.e. @property - * will be set to %TRUE if the key is not - * writable. + * will be set to %TRUE if the key is not writable. * * Note that the lifecycle of the binding is tied to the object, * and that you can have only one binding per object property. @@ -3074,7 +3051,7 @@ g_settings_action_get_state_hint (GAction *action) GSettingsAction *gsa = (GSettingsAction *) action; /* no point in reimplementing this... */ - return g_settings_get_range (gsa->settings, gsa->key.name); + return g_settings_schema_key_get_range (&gsa->key); } static void