1/*
2 * Copyright © 2009, 2010 Codethink Limited
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
16 *
17 * Author: Ryan Lortie <desrt@desrt.ca>
18 */
19
20/* Prelude {{{1 */
21#include "config.h"
22
23#include <glib.h>
24#include <glibintl.h>
25
26#include "gsettings.h"
27
28#include "gdelayedsettingsbackend.h"
29#include "gsettingsbackendinternal.h"
30#include "gsettings-mapping.h"
31#include "gsettingsschema-internal.h"
32#include "gaction.h"
33#include "gmarshal-internal.h"
34
35#include "strinfo.c"
36
37/**
38 * SECTION:gsettings
39 * @short_description: High-level API for application settings
40 * @include: gio/gio.h
41 *
42 * The #GSettings class provides a convenient API for storing and retrieving
43 * application settings.
44 *
45 * Reads and writes can be considered to be non-blocking. Reading
46 * settings with #GSettings is typically extremely fast: on
47 * approximately the same order of magnitude (but slower than) a
48 * #GHashTable lookup. Writing settings is also extremely fast in terms
49 * of time to return to your application, but can be extremely expensive
50 * for other threads and other processes. Many settings backends
51 * (including dconf) have lazy initialisation which means in the common
52 * case of the user using their computer without modifying any settings
53 * a lot of work can be avoided. For dconf, the D-Bus service doesn't
54 * even need to be started in this case. For this reason, you should
55 * only ever modify #GSettings keys in response to explicit user action.
56 * Particular care should be paid to ensure that modifications are not
57 * made during startup -- for example, when setting the initial value
58 * of preferences widgets. The built-in g_settings_bind() functionality
59 * is careful not to write settings in response to notify signals as a
60 * result of modifications that it makes to widgets.
61 *
62 * When creating a GSettings instance, you have to specify a schema
63 * that describes the keys in your settings and their types and default
64 * values, as well as some other information.
65 *
66 * Normally, a schema has a fixed path that determines where the settings
67 * are stored in the conceptual global tree of settings. However, schemas
68 * can also be '[relocatable][gsettings-relocatable]', i.e. not equipped with
69 * a fixed path. This is
70 * useful e.g. when the schema describes an 'account', and you want to be
71 * able to store a arbitrary number of accounts.
72 *
73 * Paths must start with and end with a forward slash character ('/')
74 * and must not contain two sequential slash characters. Paths should
75 * be chosen based on a domain name associated with the program or
76 * library to which the settings belong. Examples of paths are
77 * "/org/gtk/settings/file-chooser/" and "/ca/desrt/dconf-editor/".
78 * Paths should not start with "/apps/", "/desktop/" or "/system/" as
79 * they often did in GConf.
80 *
81 * Unlike other configuration systems (like GConf), GSettings does not
82 * restrict keys to basic types like strings and numbers. GSettings stores
83 * values as #GVariant, and allows any #GVariantType for keys. Key names
84 * are restricted to lowercase characters, numbers and '-'. Furthermore,
85 * the names must begin with a lowercase character, must not end
86 * with a '-', and must not contain consecutive dashes.
87 *
88 * Similar to GConf, the default values in GSettings schemas can be
89 * localized, but the localized values are stored in gettext catalogs
90 * and looked up with the domain that is specified in the
91 * `gettext-domain` attribute of the <schemalist> or <schema>
92 * elements and the category that is specified in the `l10n` attribute of
93 * the <default> element. The string which is translated includes all text in
94 * the <default> element, including any surrounding quotation marks.
95 *
96 * The `l10n` attribute must be set to `messages` or `time`, and sets the
97 * [locale category for
98 * translation](https://www.gnu.org/software/gettext/manual/html_node/Aspects.html#index-locale-categories-1).
99 * The `messages` category should be used by default; use `time` for
100 * translatable date or time formats. A translation comment can be added as an
101 * XML comment immediately above the <default> element — it is recommended to
102 * add these comments to aid translators understand the meaning and
103 * implications of the default value. An optional translation `context`
104 * attribute can be set on the <default> element to disambiguate multiple
105 * defaults which use the same string.
106 *
107 * For example:
108 * |[
109 * <!-- Translators: A list of words which are not allowed to be typed, in
110 * GVariant serialization syntax.
111 * See: https://developer.gnome.org/glib/stable/gvariant-text.html -->
112 * <default l10n='messages' context='Banned words'>['bad', 'words']</default>
113 * ]|
114 *
115 * Translations of default values must remain syntactically valid serialized
116 * #GVariants (e.g. retaining any surrounding quotation marks) or runtime
117 * errors will occur.
118 *
119 * GSettings uses schemas in a compact binary form that is created
120 * by the [glib-compile-schemas][glib-compile-schemas]
121 * utility. The input is a schema description in an XML format.
122 *
123 * A DTD for the gschema XML format can be found here:
124 * [gschema.dtd](https://git.gnome.org/browse/glib/tree/gio/gschema.dtd)
125 *
126 * The [glib-compile-schemas][glib-compile-schemas] tool expects schema
127 * files to have the extension `.gschema.xml`.
128 *
129 * At runtime, schemas are identified by their id (as specified in the
130 * id attribute of the <schema> element). The convention for schema
131 * ids is to use a dotted name, similar in style to a D-Bus bus name,
132 * e.g. "org.gnome.SessionManager". In particular, if the settings are
133 * for a specific service that owns a D-Bus bus name, the D-Bus bus name
134 * and schema id should match. For schemas which deal with settings not
135 * associated with one named application, the id should not use
136 * StudlyCaps, e.g. "org.gnome.font-rendering".
137 *
138 * In addition to #GVariant types, keys can have types that have
139 * enumerated types. These can be described by a <choice>,
140 * <enum> or <flags> element, as seen in the
141 * [example][schema-enumerated]. The underlying type of such a key
142 * is string, but you can use g_settings_get_enum(), g_settings_set_enum(),
143 * g_settings_get_flags(), g_settings_set_flags() access the numeric values
144 * corresponding to the string value of enum and flags keys.
145 *
146 * An example for default value:
147 * |[
148 * <schemalist>
149 * <schema id="org.gtk.Test" path="/org/gtk/Test/" gettext-domain="test">
150 *
151 * <key name="greeting" type="s">
152 * <default l10n="messages">"Hello, earthlings"</default>
153 * <summary>A greeting</summary>
154 * <description>
155 * Greeting of the invading martians
156 * </description>
157 * </key>
158 *
159 * <key name="box" type="(ii)">
160 * <default>(20,30)</default>
161 * </key>
162 *
163 * <key name="empty-string" type="s">
164 * <default>""</default>
165 * <summary>Empty strings have to be provided in GVariant form</summary>
166 * </key>
167 *
168 * </schema>
169 * </schemalist>
170 * ]|
171 *
172 * An example for ranges, choices and enumerated types:
173 * |[
174 * <schemalist>
175 *
176 * <enum id="org.gtk.Test.myenum">
177 * <value nick="first" value="1"/>
178 * <value nick="second" value="2"/>
179 * </enum>
180 *
181 * <flags id="org.gtk.Test.myflags">
182 * <value nick="flag1" value="1"/>
183 * <value nick="flag2" value="2"/>
184 * <value nick="flag3" value="4"/>
185 * </flags>
186 *
187 * <schema id="org.gtk.Test">
188 *
189 * <key name="key-with-range" type="i">
190 * <range min="1" max="100"/>
191 * <default>10</default>
192 * </key>
193 *
194 * <key name="key-with-choices" type="s">
195 * <choices>
196 * <choice value='Elisabeth'/>
197 * <choice value='Annabeth'/>
198 * <choice value='Joe'/>
199 * </choices>
200 * <aliases>
201 * <alias value='Anna' target='Annabeth'/>
202 * <alias value='Beth' target='Elisabeth'/>
203 * </aliases>
204 * <default>'Joe'</default>
205 * </key>
206 *
207 * <key name='enumerated-key' enum='org.gtk.Test.myenum'>
208 * <default>'first'</default>
209 * </key>
210 *
211 * <key name='flags-key' flags='org.gtk.Test.myflags'>
212 * <default>["flag1","flag2"]</default>
213 * </key>
214 * </schema>
215 * </schemalist>
216 * ]|
217 *
218 * ## Vendor overrides
219 *
220 * Default values are defined in the schemas that get installed by
221 * an application. Sometimes, it is necessary for a vendor or distributor
222 * to adjust these defaults. Since patching the XML source for the schema
223 * is inconvenient and error-prone,
224 * [glib-compile-schemas][glib-compile-schemas] reads so-called vendor
225 * override' files. These are keyfiles in the same directory as the XML
226 * schema sources which can override default values. The schema id serves
227 * as the group name in the key file, and the values are expected in
228 * serialized GVariant form, as in the following example:
229 * |[
230 * [org.gtk.Example]
231 * key1='string'
232 * key2=1.5
233 * ]|
234 *
235 * glib-compile-schemas expects schema files to have the extension
236 * `.gschema.override`.
237 *
238 * ## Binding
239 *
240 * A very convenient feature of GSettings lets you bind #GObject properties
241 * directly to settings, using g_settings_bind(). Once a GObject property
242 * has been bound to a setting, changes on either side are automatically
243 * propagated to the other side. GSettings handles details like mapping
244 * between GObject and GVariant types, and preventing infinite cycles.
245 *
246 * This makes it very easy to hook up a preferences dialog to the
247 * underlying settings. To make this even more convenient, GSettings
248 * looks for a boolean property with the name "sensitivity" and
249 * automatically binds it to the writability of the bound setting.
250 * If this 'magic' gets in the way, it can be suppressed with the
251 * #G_SETTINGS_BIND_NO_SENSITIVITY flag.
252 *
253 * ## Relocatable schemas # {#gsettings-relocatable}
254 *
255 * A relocatable schema is one with no `path` attribute specified on its
256 * <schema> element. By using g_settings_new_with_path(), a #GSettings object
257 * can be instantiated for a relocatable schema, assigning a path to the
258 * instance. Paths passed to g_settings_new_with_path() will typically be
259 * constructed dynamically from a constant prefix plus some form of instance
260 * identifier; but they must still be valid GSettings paths. Paths could also
261 * be constant and used with a globally installed schema originating from a
262 * dependency library.
263 *
264 * For example, a relocatable schema could be used to store geometry information
265 * for different windows in an application. If the schema ID was
266 * `org.foo.MyApp.Window`, it could be instantiated for paths
267 * `/org/foo/MyApp/main/`, `/org/foo/MyApp/document-1/`,
268 * `/org/foo/MyApp/document-2/`, etc. If any of the paths are well-known
269 * they can be specified as <child> elements in the parent schema, e.g.:
270 * |[
271 * <schema id="org.foo.MyApp" path="/org/foo/MyApp/">
272 * <child name="main" schema="org.foo.MyApp.Window"/>
273 * </schema>
274 * ]|
275 *
276 * ## Build system integration # {#gsettings-build-system}
277 *
278 * GSettings comes with autotools integration to simplify compiling and
279 * installing schemas. To add GSettings support to an application, add the
280 * following to your `configure.ac`:
281 * |[
282 * GLIB_GSETTINGS
283 * ]|
284 *
285 * In the appropriate `Makefile.am`, use the following snippet to compile and
286 * install the named schema:
287 * |[
288 * gsettings_SCHEMAS = org.foo.MyApp.gschema.xml
289 * EXTRA_DIST = $(gsettings_SCHEMAS)
290 *
291 * @GSETTINGS_RULES@
292 * ]|
293 *
294 * No changes are needed to the build system to mark a schema XML file for
295 * translation. Assuming it sets the `gettext-domain` attribute, a schema may
296 * be marked for translation by adding it to `POTFILES.in`, assuming gettext
297 * 0.19 is in use (the preferred method for translation):
298 * |[
299 * data/org.foo.MyApp.gschema.xml
300 * ]|
301 *
302 * Alternatively, if intltool 0.50.1 is in use:
303 * |[
304 * [type: gettext/gsettings]data/org.foo.MyApp.gschema.xml
305 * ]|
306 *
307 * GSettings will use gettext to look up translations for the <summary> and
308 * <description> elements, and also any <default> elements which have a `l10n`
309 * attribute set. Translations must not be included in the `.gschema.xml` file
310 * by the build system, for example by using intltool XML rules with a
311 * `.gschema.xml.in` template.
312 *
313 * If an enumerated type defined in a C header file is to be used in a GSettings
314 * schema, it can either be defined manually using an <enum> element in the
315 * schema XML, or it can be extracted automatically from the C header. This
316 * approach is preferred, as it ensures the two representations are always
317 * synchronised. To do so, add the following to the relevant `Makefile.am`:
318 * |[
319 * gsettings_ENUM_NAMESPACE = org.foo.MyApp
320 * gsettings_ENUM_FILES = my-app-enums.h my-app-misc.h
321 * ]|
322 *
323 * `gsettings_ENUM_NAMESPACE` specifies the schema namespace for the enum files,
324 * which are specified in `gsettings_ENUM_FILES`. This will generate a
325 * `org.foo.MyApp.enums.xml` file containing the extracted enums, which will be
326 * automatically included in the schema compilation, install and uninstall
327 * rules. It should not be committed to version control or included in
328 * `EXTRA_DIST`.
329 */
330
331/**
332 * GSettings:
333 *
334 * #GSettings is an opaque data structure and can only be accessed
335 * using the following functions.
336 **/
337
338struct _GSettingsPrivate
339{
340 /* where the signals go... */
341 GMainContext *main_context;
342
343 GSettingsBackend *backend;
344 GSettingsSchema *schema;
345 gchar *path;
346
347 GDelayedSettingsBackend *delayed;
348};
349
350enum
351{
352 PROP_0,
353 PROP_SCHEMA,
354 PROP_SCHEMA_ID,
355 PROP_BACKEND,
356 PROP_PATH,
357 PROP_HAS_UNAPPLIED,
358 PROP_DELAY_APPLY
359};
360
361enum
362{
363 SIGNAL_WRITABLE_CHANGE_EVENT,
364 SIGNAL_WRITABLE_CHANGED,
365 SIGNAL_CHANGE_EVENT,
366 SIGNAL_CHANGED,
367 N_SIGNALS
368};
369
370static guint g_settings_signals[N_SIGNALS];
371
372G_DEFINE_TYPE_WITH_PRIVATE (GSettings, g_settings, G_TYPE_OBJECT)
373
374/* Signals {{{1 */
375static gboolean
376g_settings_real_change_event (GSettings *settings,
377 const GQuark *keys,
378 gint n_keys)
379{
380 gint i;
381
382 if (keys == NULL)
383 keys = g_settings_schema_list (schema: settings->priv->schema, n_items: &n_keys);
384
385 for (i = 0; i < n_keys; i++)
386 {
387 const gchar *key = g_quark_to_string (quark: keys[i]);
388
389 if (g_str_has_suffix (str: key, suffix: "/"))
390 continue;
391
392 g_signal_emit (instance: settings, signal_id: g_settings_signals[SIGNAL_CHANGED], detail: keys[i], key);
393 }
394
395 return FALSE;
396}
397
398static gboolean
399g_settings_real_writable_change_event (GSettings *settings,
400 GQuark key)
401{
402 const GQuark *keys = &key;
403 gint n_keys = 1;
404 gint i;
405
406 if (key == 0)
407 keys = g_settings_schema_list (schema: settings->priv->schema, n_items: &n_keys);
408
409 for (i = 0; i < n_keys; i++)
410 {
411 const gchar *key = g_quark_to_string (quark: keys[i]);
412
413 if (g_str_has_suffix (str: key, suffix: "/"))
414 continue;
415
416 g_signal_emit (instance: settings, signal_id: g_settings_signals[SIGNAL_WRITABLE_CHANGED], detail: keys[i], key);
417 }
418
419 return FALSE;
420}
421
422static void
423settings_backend_changed (GObject *target,
424 GSettingsBackend *backend,
425 const gchar *key,
426 gpointer origin_tag)
427{
428 GSettings *settings = G_SETTINGS (target);
429 gboolean ignore_this;
430 gint i;
431
432 /* We used to assert here:
433 *
434 * settings->priv->backend == backend
435 *
436 * but it could be the case that a notification is queued for delivery
437 * while someone calls g_settings_delay() (which changes the backend).
438 *
439 * Since the delay backend would just pass that straight through
440 * anyway, it doesn't make sense to try to detect this case.
441 * Therefore, we just accept it.
442 */
443
444 for (i = 0; key[i] == settings->priv->path[i]; i++);
445
446 if (settings->priv->path[i] == '\0' &&
447 g_settings_schema_has_key (schema: settings->priv->schema, name: key + i))
448 {
449 GQuark quark;
450
451 quark = g_quark_from_string (string: key + i);
452 g_signal_emit (instance: settings, signal_id: g_settings_signals[SIGNAL_CHANGE_EVENT],
453 detail: 0, &quark, 1, &ignore_this);
454 }
455}
456
457static void
458settings_backend_path_changed (GObject *target,
459 GSettingsBackend *backend,
460 const gchar *path,
461 gpointer origin_tag)
462{
463 GSettings *settings = G_SETTINGS (target);
464 gboolean ignore_this;
465
466 if (g_str_has_prefix (str: settings->priv->path, prefix: path))
467 g_signal_emit (instance: settings, signal_id: g_settings_signals[SIGNAL_CHANGE_EVENT],
468 detail: 0, NULL, 0, &ignore_this);
469}
470
471static void
472settings_backend_keys_changed (GObject *target,
473 GSettingsBackend *backend,
474 const gchar *path,
475 gpointer origin_tag,
476 const gchar * const *items)
477{
478 GSettings *settings = G_SETTINGS (target);
479 gboolean ignore_this;
480 gint i;
481
482 for (i = 0; settings->priv->path[i] &&
483 settings->priv->path[i] == path[i]; i++);
484
485 if (path[i] == '\0')
486 {
487 GQuark quarks[256];
488 gint j, l = 0;
489
490 for (j = 0; items[j]; j++)
491 {
492 const gchar *item = items[j];
493 gint k;
494
495 for (k = 0; item[k] == settings->priv->path[i + k]; k++);
496
497 if (settings->priv->path[i + k] == '\0' &&
498 g_settings_schema_has_key (schema: settings->priv->schema, name: item + k))
499 quarks[l++] = g_quark_from_string (string: item + k);
500
501 /* "256 quarks ought to be enough for anybody!"
502 * If this bites you, I'm sorry. Please file a bug.
503 */
504 g_assert (l < 256);
505 }
506
507 if (l > 0)
508 g_signal_emit (instance: settings, signal_id: g_settings_signals[SIGNAL_CHANGE_EVENT],
509 detail: 0, quarks, l, &ignore_this);
510 }
511}
512
513static void
514settings_backend_writable_changed (GObject *target,
515 GSettingsBackend *backend,
516 const gchar *key)
517{
518 GSettings *settings = G_SETTINGS (target);
519 gboolean ignore_this;
520 gint i;
521
522 for (i = 0; key[i] == settings->priv->path[i]; i++);
523
524 if (settings->priv->path[i] == '\0' &&
525 g_settings_schema_has_key (schema: settings->priv->schema, name: key + i))
526 g_signal_emit (instance: settings, signal_id: g_settings_signals[SIGNAL_WRITABLE_CHANGE_EVENT],
527 detail: 0, g_quark_from_string (string: key + i), &ignore_this);
528}
529
530static void
531settings_backend_path_writable_changed (GObject *target,
532 GSettingsBackend *backend,
533 const gchar *path)
534{
535 GSettings *settings = G_SETTINGS (target);
536 gboolean ignore_this;
537
538 if (g_str_has_prefix (str: settings->priv->path, prefix: path))
539 g_signal_emit (instance: settings, signal_id: g_settings_signals[SIGNAL_WRITABLE_CHANGE_EVENT],
540 detail: 0, (GQuark) 0, &ignore_this);
541}
542
543/* Properties, Construction, Destruction {{{1 */
544static void
545g_settings_set_property (GObject *object,
546 guint prop_id,
547 const GValue *value,
548 GParamSpec *pspec)
549{
550 GSettings *settings = G_SETTINGS (object);
551
552 switch (prop_id)
553 {
554 case PROP_SCHEMA:
555 {
556 GSettingsSchema *schema;
557
558 schema = g_value_dup_boxed (value);
559
560 /* we receive a set_property() call for "settings-schema" even
561 * if it was not specified (ie: with NULL value). ->schema
562 * could already be set at this point (ie: via "schema-id").
563 * check for NULL to avoid clobbering the existing value.
564 */
565 if (schema != NULL)
566 {
567 g_assert (settings->priv->schema == NULL);
568 settings->priv->schema = schema;
569 }
570 }
571 break;
572
573 case PROP_SCHEMA_ID:
574 {
575 const gchar *schema_id;
576
577 schema_id = g_value_get_string (value);
578
579 /* we receive a set_property() call for both "schema" and
580 * "schema-id", even if they are not set. Hopefully only one of
581 * them is non-NULL.
582 */
583 if (schema_id != NULL)
584 {
585 GSettingsSchemaSource *default_source;
586
587 g_assert (settings->priv->schema == NULL);
588 default_source = g_settings_schema_source_get_default ();
589
590 if (default_source == NULL)
591 g_error ("No GSettings schemas are installed on the system");
592
593 settings->priv->schema = g_settings_schema_source_lookup (source: default_source, schema_id, TRUE);
594
595 if (settings->priv->schema == NULL)
596 g_error ("Settings schema '%s' is not installed", schema_id);
597 }
598 }
599 break;
600
601 case PROP_PATH:
602 settings->priv->path = g_value_dup_string (value);
603 break;
604
605 case PROP_BACKEND:
606 settings->priv->backend = g_value_dup_object (value);
607 break;
608
609 default:
610 g_assert_not_reached ();
611 }
612}
613
614static void
615g_settings_get_property (GObject *object,
616 guint prop_id,
617 GValue *value,
618 GParamSpec *pspec)
619{
620 GSettings *settings = G_SETTINGS (object);
621
622 switch (prop_id)
623 {
624 case PROP_SCHEMA:
625 g_value_set_boxed (value, v_boxed: settings->priv->schema);
626 break;
627
628 case PROP_SCHEMA_ID:
629 g_value_set_string (value, v_string: g_settings_schema_get_id (schema: settings->priv->schema));
630 break;
631
632 case PROP_BACKEND:
633 g_value_set_object (value, v_object: settings->priv->backend);
634 break;
635
636 case PROP_PATH:
637 g_value_set_string (value, v_string: settings->priv->path);
638 break;
639
640 case PROP_HAS_UNAPPLIED:
641 g_value_set_boolean (value, v_boolean: g_settings_get_has_unapplied (settings));
642 break;
643
644 case PROP_DELAY_APPLY:
645 g_value_set_boolean (value, v_boolean: settings->priv->delayed != NULL);
646 break;
647
648 default:
649 g_assert_not_reached ();
650 }
651}
652
653static const GSettingsListenerVTable listener_vtable = {
654 settings_backend_changed,
655 settings_backend_path_changed,
656 settings_backend_keys_changed,
657 settings_backend_writable_changed,
658 settings_backend_path_writable_changed
659};
660
661static void
662g_settings_constructed (GObject *object)
663{
664 GSettings *settings = G_SETTINGS (object);
665 const gchar *schema_path;
666
667 schema_path = g_settings_schema_get_path (schema: settings->priv->schema);
668
669 if (settings->priv->path && schema_path && strcmp (s1: settings->priv->path, s2: schema_path) != 0)
670 g_error ("settings object created with schema '%s' and path '%s', but path '%s' is specified by schema",
671 g_settings_schema_get_id (settings->priv->schema), settings->priv->path, schema_path);
672
673 if (settings->priv->path == NULL)
674 {
675 if (schema_path == NULL)
676 g_error ("attempting to create schema '%s' without a path",
677 g_settings_schema_get_id (settings->priv->schema));
678
679 settings->priv->path = g_strdup (str: schema_path);
680 }
681
682 if (settings->priv->backend == NULL)
683 settings->priv->backend = g_settings_backend_get_default ();
684
685 g_settings_backend_watch (backend: settings->priv->backend,
686 vtable: &listener_vtable, G_OBJECT (settings),
687 context: settings->priv->main_context);
688 g_settings_backend_subscribe (backend: settings->priv->backend,
689 name: settings->priv->path);
690}
691
692static void
693g_settings_finalize (GObject *object)
694{
695 GSettings *settings = G_SETTINGS (object);
696
697 g_settings_backend_unsubscribe (backend: settings->priv->backend,
698 name: settings->priv->path);
699 g_main_context_unref (context: settings->priv->main_context);
700 g_object_unref (object: settings->priv->backend);
701 g_settings_schema_unref (schema: settings->priv->schema);
702 g_free (mem: settings->priv->path);
703
704 G_OBJECT_CLASS (g_settings_parent_class)->finalize (object);
705}
706
707static void
708g_settings_init (GSettings *settings)
709{
710 settings->priv = g_settings_get_instance_private (self: settings);
711 settings->priv->main_context = g_main_context_ref_thread_default ();
712}
713
714static void
715g_settings_class_init (GSettingsClass *class)
716{
717 GObjectClass *object_class = G_OBJECT_CLASS (class);
718
719 class->writable_change_event = g_settings_real_writable_change_event;
720 class->change_event = g_settings_real_change_event;
721
722 object_class->set_property = g_settings_set_property;
723 object_class->get_property = g_settings_get_property;
724 object_class->constructed = g_settings_constructed;
725 object_class->finalize = g_settings_finalize;
726
727 /**
728 * GSettings::changed:
729 * @settings: the object on which the signal was emitted
730 * @key: the name of the key that changed
731 *
732 * The "changed" signal is emitted when a key has potentially changed.
733 * You should call one of the g_settings_get() calls to check the new
734 * value.
735 *
736 * This signal supports detailed connections. You can connect to the
737 * detailed signal "changed::x" in order to only receive callbacks
738 * when key "x" changes.
739 *
740 * Note that @settings only emits this signal if you have read @key at
741 * least once while a signal handler was already connected for @key.
742 */
743 g_settings_signals[SIGNAL_CHANGED] =
744 g_signal_new (I_("changed"), G_TYPE_SETTINGS,
745 signal_flags: G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
746 G_STRUCT_OFFSET (GSettingsClass, changed),
747 NULL, NULL, NULL, G_TYPE_NONE,
748 n_params: 1, G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE);
749
750 /**
751 * GSettings::change-event:
752 * @settings: the object on which the signal was emitted
753 * @keys: (array length=n_keys) (element-type GQuark) (nullable):
754 * an array of #GQuarks for the changed keys, or %NULL
755 * @n_keys: the length of the @keys array, or 0
756 *
757 * The "change-event" signal is emitted once per change event that
758 * affects this settings object. You should connect to this signal
759 * only if you are interested in viewing groups of changes before they
760 * are split out into multiple emissions of the "changed" signal.
761 * For most use cases it is more appropriate to use the "changed" signal.
762 *
763 * In the event that the change event applies to one or more specified
764 * keys, @keys will be an array of #GQuark of length @n_keys. In the
765 * event that the change event applies to the #GSettings object as a
766 * whole (ie: potentially every key has been changed) then @keys will
767 * be %NULL and @n_keys will be 0.
768 *
769 * The default handler for this signal invokes the "changed" signal
770 * for each affected key. If any other connected handler returns
771 * %TRUE then this default functionality will be suppressed.
772 *
773 * Returns: %TRUE to stop other handlers from being invoked for the
774 * event. FALSE to propagate the event further.
775 */
776 g_settings_signals[SIGNAL_CHANGE_EVENT] =
777 g_signal_new (I_("change-event"), G_TYPE_SETTINGS,
778 signal_flags: G_SIGNAL_RUN_LAST,
779 G_STRUCT_OFFSET (GSettingsClass, change_event),
780 accumulator: g_signal_accumulator_true_handled, NULL,
781 c_marshaller: _g_cclosure_marshal_BOOLEAN__POINTER_INT,
782 G_TYPE_BOOLEAN, n_params: 2, G_TYPE_POINTER, G_TYPE_INT);
783 g_signal_set_va_marshaller (signal_id: g_settings_signals[SIGNAL_CHANGE_EVENT],
784 G_TYPE_FROM_CLASS (class),
785 va_marshaller: _g_cclosure_marshal_BOOLEAN__POINTER_INTv);
786
787 /**
788 * GSettings::writable-changed:
789 * @settings: the object on which the signal was emitted
790 * @key: the key
791 *
792 * The "writable-changed" signal is emitted when the writability of a
793 * key has potentially changed. You should call
794 * g_settings_is_writable() in order to determine the new status.
795 *
796 * This signal supports detailed connections. You can connect to the
797 * detailed signal "writable-changed::x" in order to only receive
798 * callbacks when the writability of "x" changes.
799 */
800 g_settings_signals[SIGNAL_WRITABLE_CHANGED] =
801 g_signal_new (I_("writable-changed"), G_TYPE_SETTINGS,
802 signal_flags: G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
803 G_STRUCT_OFFSET (GSettingsClass, writable_changed),
804 NULL, NULL, NULL, G_TYPE_NONE,
805 n_params: 1, G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE);
806
807 /**
808 * GSettings::writable-change-event:
809 * @settings: the object on which the signal was emitted
810 * @key: the quark of the key, or 0
811 *
812 * The "writable-change-event" signal is emitted once per writability
813 * change event that affects this settings object. You should connect
814 * to this signal if you are interested in viewing groups of changes
815 * before they are split out into multiple emissions of the
816 * "writable-changed" signal. For most use cases it is more
817 * appropriate to use the "writable-changed" signal.
818 *
819 * In the event that the writability change applies only to a single
820 * key, @key will be set to the #GQuark for that key. In the event
821 * that the writability change affects the entire settings object,
822 * @key will be 0.
823 *
824 * The default handler for this signal invokes the "writable-changed"
825 * and "changed" signals for each affected key. This is done because
826 * changes in writability might also imply changes in value (if for
827 * example, a new mandatory setting is introduced). If any other
828 * connected handler returns %TRUE then this default functionality
829 * will be suppressed.
830 *
831 * Returns: %TRUE to stop other handlers from being invoked for the
832 * event. FALSE to propagate the event further.
833 */
834 g_settings_signals[SIGNAL_WRITABLE_CHANGE_EVENT] =
835 g_signal_new (I_("writable-change-event"), G_TYPE_SETTINGS,
836 signal_flags: G_SIGNAL_RUN_LAST,
837 G_STRUCT_OFFSET (GSettingsClass, writable_change_event),
838 accumulator: g_signal_accumulator_true_handled, NULL,
839 c_marshaller: _g_cclosure_marshal_BOOLEAN__UINT,
840 G_TYPE_BOOLEAN, n_params: 1, G_TYPE_UINT);
841 g_signal_set_va_marshaller (signal_id: g_settings_signals[SIGNAL_WRITABLE_CHANGE_EVENT],
842 G_TYPE_FROM_CLASS (class),
843 va_marshaller: _g_cclosure_marshal_BOOLEAN__UINTv);
844
845 /**
846 * GSettings:backend:
847 *
848 * The name of the context that the settings are stored in.
849 */
850 g_object_class_install_property (oclass: object_class, property_id: PROP_BACKEND,
851 pspec: g_param_spec_object (name: "backend",
852 P_("GSettingsBackend"),
853 P_("The GSettingsBackend for this settings object"),
854 G_TYPE_SETTINGS_BACKEND, flags: G_PARAM_CONSTRUCT_ONLY |
855 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
856
857 /**
858 * GSettings:settings-schema:
859 *
860 * The #GSettingsSchema describing the types of keys for this
861 * #GSettings object.
862 *
863 * Ideally, this property would be called 'schema'. #GSettingsSchema
864 * has only existed since version 2.32, however, and before then the
865 * 'schema' property was used to refer to the ID of the schema rather
866 * than the schema itself. Take care.
867 */
868 g_object_class_install_property (oclass: object_class, property_id: PROP_SCHEMA,
869 pspec: g_param_spec_boxed (name: "settings-schema",
870 P_("schema"),
871 P_("The GSettingsSchema for this settings object"),
872 G_TYPE_SETTINGS_SCHEMA,
873 flags: G_PARAM_CONSTRUCT_ONLY |
874 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
875
876 /**
877 * GSettings:schema:
878 *
879 * The name of the schema that describes the types of keys
880 * for this #GSettings object.
881 *
882 * The type of this property is *not* #GSettingsSchema.
883 * #GSettingsSchema has only existed since version 2.32 and
884 * unfortunately this name was used in previous versions to refer to
885 * the schema ID rather than the schema itself. Take care to use the
886 * 'settings-schema' property if you wish to pass in a
887 * #GSettingsSchema.
888 *
889 * Deprecated:2.32:Use the 'schema-id' property instead. In a future
890 * version, this property may instead refer to a #GSettingsSchema.
891 */
892 g_object_class_install_property (oclass: object_class, property_id: PROP_SCHEMA_ID,
893 pspec: g_param_spec_string (name: "schema",
894 P_("Schema name"),
895 P_("The name of the schema for this settings object"),
896 NULL,
897 flags: G_PARAM_CONSTRUCT_ONLY |
898 G_PARAM_DEPRECATED | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
899
900 /**
901 * GSettings:schema-id:
902 *
903 * The name of the schema that describes the types of keys
904 * for this #GSettings object.
905 */
906 g_object_class_install_property (oclass: object_class, property_id: PROP_SCHEMA_ID,
907 pspec: g_param_spec_string (name: "schema-id",
908 P_("Schema name"),
909 P_("The name of the schema for this settings object"),
910 NULL,
911 flags: G_PARAM_CONSTRUCT_ONLY |
912 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
913
914 /**
915 * GSettings:path:
916 *
917 * The path within the backend where the settings are stored.
918 */
919 g_object_class_install_property (oclass: object_class, property_id: PROP_PATH,
920 pspec: g_param_spec_string (name: "path",
921 P_("Base path"),
922 P_("The path within the backend where the settings are"),
923 NULL,
924 flags: G_PARAM_CONSTRUCT_ONLY |
925 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
926
927 /**
928 * GSettings:has-unapplied:
929 *
930 * If this property is %TRUE, the #GSettings object has outstanding
931 * changes that will be applied when g_settings_apply() is called.
932 */
933 g_object_class_install_property (oclass: object_class, property_id: PROP_HAS_UNAPPLIED,
934 pspec: g_param_spec_boolean (name: "has-unapplied",
935 P_("Has unapplied changes"),
936 P_("TRUE if there are outstanding changes to apply()"),
937 FALSE,
938 flags: G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
939
940 /**
941 * GSettings:delay-apply:
942 *
943 * Whether the #GSettings object is in 'delay-apply' mode. See
944 * g_settings_delay() for details.
945 *
946 * Since: 2.28
947 */
948 g_object_class_install_property (oclass: object_class, property_id: PROP_DELAY_APPLY,
949 pspec: g_param_spec_boolean (name: "delay-apply",
950 P_("Delay-apply mode"),
951 P_("Whether this settings object is in “delay-apply” mode"),
952 FALSE,
953 flags: G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
954}
955
956/* Construction (new, new_with_path, etc.) {{{1 */
957/**
958 * g_settings_new:
959 * @schema_id: the id of the schema
960 *
961 * Creates a new #GSettings object with the schema specified by
962 * @schema_id.
963 *
964 * It is an error for the schema to not exist: schemas are an
965 * essential part of a program, as they provide type information.
966 * If schemas need to be dynamically loaded (for example, from an
967 * optional runtime dependency), g_settings_schema_source_lookup()
968 * can be used to test for their existence before loading them.
969 *
970 * Signals on the newly created #GSettings object will be dispatched
971 * via the thread-default #GMainContext in effect at the time of the
972 * call to g_settings_new(). The new #GSettings will hold a reference
973 * on the context. See g_main_context_push_thread_default().
974 *
975 * Returns: a new #GSettings object
976 *
977 * Since: 2.26
978 */
979GSettings *
980g_settings_new (const gchar *schema_id)
981{
982 g_return_val_if_fail (schema_id != NULL, NULL);
983
984 return g_object_new (G_TYPE_SETTINGS,
985 first_property_name: "schema-id", schema_id,
986 NULL);
987}
988
989static gboolean
990path_is_valid (const gchar *path)
991{
992 if (!path)
993 return FALSE;
994
995 if (path[0] != '/')
996 return FALSE;
997
998 if (!g_str_has_suffix (str: path, suffix: "/"))
999 return FALSE;
1000
1001 return strstr (haystack: path, needle: "//") == NULL;
1002}
1003
1004/**
1005 * g_settings_new_with_path:
1006 * @schema_id: the id of the schema
1007 * @path: the path to use
1008 *
1009 * Creates a new #GSettings object with the relocatable schema specified
1010 * by @schema_id and a given path.
1011 *
1012 * You only need to do this if you want to directly create a settings
1013 * object with a schema that doesn't have a specified path of its own.
1014 * That's quite rare.
1015 *
1016 * It is a programmer error to call this function for a schema that
1017 * has an explicitly specified path.
1018 *
1019 * It is a programmer error if @path is not a valid path. A valid path
1020 * begins and ends with '/' and does not contain two consecutive '/'
1021 * characters.
1022 *
1023 * Returns: a new #GSettings object
1024 *
1025 * Since: 2.26
1026 */
1027GSettings *
1028g_settings_new_with_path (const gchar *schema_id,
1029 const gchar *path)
1030{
1031 g_return_val_if_fail (schema_id != NULL, NULL);
1032 g_return_val_if_fail (path_is_valid (path), NULL);
1033
1034 return g_object_new (G_TYPE_SETTINGS,
1035 first_property_name: "schema-id", schema_id,
1036 "path", path,
1037 NULL);
1038}
1039
1040/**
1041 * g_settings_new_with_backend:
1042 * @schema_id: the id of the schema
1043 * @backend: the #GSettingsBackend to use
1044 *
1045 * Creates a new #GSettings object with the schema specified by
1046 * @schema_id and a given #GSettingsBackend.
1047 *
1048 * Creating a #GSettings object with a different backend allows accessing
1049 * settings from a database other than the usual one. For example, it may make
1050 * sense to pass a backend corresponding to the "defaults" settings database on
1051 * the system to get a settings object that modifies the system default
1052 * settings instead of the settings for this user.
1053 *
1054 * Returns: a new #GSettings object
1055 *
1056 * Since: 2.26
1057 */
1058GSettings *
1059g_settings_new_with_backend (const gchar *schema_id,
1060 GSettingsBackend *backend)
1061{
1062 g_return_val_if_fail (schema_id != NULL, NULL);
1063 g_return_val_if_fail (G_IS_SETTINGS_BACKEND (backend), NULL);
1064
1065 return g_object_new (G_TYPE_SETTINGS,
1066 first_property_name: "schema-id", schema_id,
1067 "backend", backend,
1068 NULL);
1069}
1070
1071/**
1072 * g_settings_new_with_backend_and_path:
1073 * @schema_id: the id of the schema
1074 * @backend: the #GSettingsBackend to use
1075 * @path: the path to use
1076 *
1077 * Creates a new #GSettings object with the schema specified by
1078 * @schema_id and a given #GSettingsBackend and path.
1079 *
1080 * This is a mix of g_settings_new_with_backend() and
1081 * g_settings_new_with_path().
1082 *
1083 * Returns: a new #GSettings object
1084 *
1085 * Since: 2.26
1086 */
1087GSettings *
1088g_settings_new_with_backend_and_path (const gchar *schema_id,
1089 GSettingsBackend *backend,
1090 const gchar *path)
1091{
1092 g_return_val_if_fail (schema_id != NULL, NULL);
1093 g_return_val_if_fail (G_IS_SETTINGS_BACKEND (backend), NULL);
1094 g_return_val_if_fail (path_is_valid (path), NULL);
1095
1096 return g_object_new (G_TYPE_SETTINGS,
1097 first_property_name: "schema-id", schema_id,
1098 "backend", backend,
1099 "path", path,
1100 NULL);
1101}
1102
1103/**
1104 * g_settings_new_full:
1105 * @schema: a #GSettingsSchema
1106 * @backend: (nullable): a #GSettingsBackend
1107 * @path: (nullable): the path to use
1108 *
1109 * Creates a new #GSettings object with a given schema, backend and
1110 * path.
1111 *
1112 * It should be extremely rare that you ever want to use this function.
1113 * It is made available for advanced use-cases (such as plugin systems
1114 * that want to provide access to schemas loaded from custom locations,
1115 * etc).
1116 *
1117 * At the most basic level, a #GSettings object is a pure composition of
1118 * 4 things: a #GSettingsSchema, a #GSettingsBackend, a path within that
1119 * backend, and a #GMainContext to which signals are dispatched.
1120 *
1121 * This constructor therefore gives you full control over constructing
1122 * #GSettings instances. The first 3 parameters are given directly as
1123 * @schema, @backend and @path, and the main context is taken from the
1124 * thread-default (as per g_settings_new()).
1125 *
1126 * If @backend is %NULL then the default backend is used.
1127 *
1128 * If @path is %NULL then the path from the schema is used. It is an
1129 * error if @path is %NULL and the schema has no path of its own or if
1130 * @path is non-%NULL and not equal to the path that the schema does
1131 * have.
1132 *
1133 * Returns: a new #GSettings object
1134 *
1135 * Since: 2.32
1136 */
1137GSettings *
1138g_settings_new_full (GSettingsSchema *schema,
1139 GSettingsBackend *backend,
1140 const gchar *path)
1141{
1142 g_return_val_if_fail (schema != NULL, NULL);
1143 g_return_val_if_fail (backend == NULL || G_IS_SETTINGS_BACKEND (backend), NULL);
1144 g_return_val_if_fail (path == NULL || path_is_valid (path), NULL);
1145
1146 return g_object_new (G_TYPE_SETTINGS,
1147 first_property_name: "settings-schema", schema,
1148 "backend", backend,
1149 "path", path,
1150 NULL);
1151}
1152
1153/* Internal read/write utilities {{{1 */
1154
1155/* @value will be sunk */
1156static gboolean
1157g_settings_write_to_backend (GSettings *settings,
1158 GSettingsSchemaKey *key,
1159 GVariant *value)
1160{
1161 gboolean success;
1162 gchar *path;
1163
1164 path = g_strconcat (string1: settings->priv->path, key->name, NULL);
1165 success = g_settings_backend_write (backend: settings->priv->backend, key: path, value, NULL);
1166 g_free (mem: path);
1167
1168 return success;
1169}
1170
1171static GVariant *
1172g_settings_read_from_backend (GSettings *settings,
1173 GSettingsSchemaKey *key,
1174 gboolean user_value_only,
1175 gboolean default_value)
1176{
1177 GVariant *value;
1178 GVariant *fixup;
1179 gchar *path;
1180
1181 path = g_strconcat (string1: settings->priv->path, key->name, NULL);
1182 if (user_value_only)
1183 value = g_settings_backend_read_user_value (backend: settings->priv->backend, key: path, expected_type: key->type);
1184 else
1185 value = g_settings_backend_read (backend: settings->priv->backend, key: path, expected_type: key->type, default_value);
1186 g_free (mem: path);
1187
1188 if (value != NULL)
1189 {
1190 fixup = g_settings_schema_key_range_fixup (key, value);
1191 g_variant_unref (value);
1192 }
1193 else
1194 fixup = NULL;
1195
1196 return fixup;
1197}
1198
1199/* Public Get/Set API {{{1 (get, get_value, set, set_value, get_mapped) */
1200/**
1201 * g_settings_get_value:
1202 * @settings: a #GSettings object
1203 * @key: the key to get the value for
1204 *
1205 * Gets the value that is stored in @settings for @key.
1206 *
1207 * It is a programmer error to give a @key that isn't contained in the
1208 * schema for @settings.
1209 *
1210 * Returns: a new #GVariant
1211 *
1212 * Since: 2.26
1213 */
1214GVariant *
1215g_settings_get_value (GSettings *settings,
1216 const gchar *key)
1217{
1218 GSettingsSchemaKey skey;
1219 GVariant *value;
1220
1221 g_return_val_if_fail (G_IS_SETTINGS (settings), NULL);
1222 g_return_val_if_fail (key != NULL, NULL);
1223
1224 g_settings_schema_key_init (key: &skey, schema: settings->priv->schema, name: key);
1225 value = g_settings_read_from_backend (settings, key: &skey, FALSE, FALSE);
1226
1227 if (value == NULL)
1228 value = g_settings_schema_key_get_default_value (key: &skey);
1229
1230 g_settings_schema_key_clear (key: &skey);
1231
1232 return value;
1233}
1234
1235/**
1236 * g_settings_get_user_value:
1237 * @settings: a #GSettings object
1238 * @key: the key to get the user value for
1239 *
1240 * Checks the "user value" of a key, if there is one.
1241 *
1242 * The user value of a key is the last value that was set by the user.
1243 *
1244 * After calling g_settings_reset() this function should always return
1245 * %NULL (assuming something is not wrong with the system
1246 * configuration).
1247 *
1248 * It is possible that g_settings_get_value() will return a different
1249 * value than this function. This can happen in the case that the user
1250 * set a value for a key that was subsequently locked down by the system
1251 * administrator -- this function will return the user's old value.
1252 *
1253 * This function may be useful for adding a "reset" option to a UI or
1254 * for providing indication that a particular value has been changed.
1255 *
1256 * It is a programmer error to give a @key that isn't contained in the
1257 * schema for @settings.
1258 *
1259 * Returns: (nullable) (transfer full): the user's value, if set
1260 *
1261 * Since: 2.40
1262 **/
1263GVariant *
1264g_settings_get_user_value (GSettings *settings,
1265 const gchar *key)
1266{
1267 GSettingsSchemaKey skey;
1268 GVariant *value;
1269
1270 g_return_val_if_fail (G_IS_SETTINGS (settings), NULL);
1271 g_return_val_if_fail (key != NULL, NULL);
1272
1273 g_settings_schema_key_init (key: &skey, schema: settings->priv->schema, name: key);
1274 value = g_settings_read_from_backend (settings, key: &skey, TRUE, FALSE);
1275 g_settings_schema_key_clear (key: &skey);
1276
1277 return value;
1278}
1279
1280/**
1281 * g_settings_get_default_value:
1282 * @settings: a #GSettings object
1283 * @key: the key to get the default value for
1284 *
1285 * Gets the "default value" of a key.
1286 *
1287 * This is the value that would be read if g_settings_reset() were to be
1288 * called on the key.
1289 *
1290 * Note that this may be a different value than returned by
1291 * g_settings_schema_key_get_default_value() if the system administrator
1292 * has provided a default value.
1293 *
1294 * Comparing the return values of g_settings_get_default_value() and
1295 * g_settings_get_value() is not sufficient for determining if a value
1296 * has been set because the user may have explicitly set the value to
1297 * something that happens to be equal to the default. The difference
1298 * here is that if the default changes in the future, the user's key
1299 * will still be set.
1300 *
1301 * This function may be useful for adding an indication to a UI of what
1302 * the default value was before the user set it.
1303 *
1304 * It is a programmer error to give a @key that isn't contained in the
1305 * schema for @settings.
1306 *
1307 * Returns: (nullable) (transfer full): the default value
1308 *
1309 * Since: 2.40
1310 **/
1311GVariant *
1312g_settings_get_default_value (GSettings *settings,
1313 const gchar *key)
1314{
1315 GSettingsSchemaKey skey;
1316 GVariant *value;
1317
1318 g_return_val_if_fail (G_IS_SETTINGS (settings), NULL);
1319 g_return_val_if_fail (key != NULL, NULL);
1320
1321 g_settings_schema_key_init (key: &skey, schema: settings->priv->schema, name: key);
1322 value = g_settings_read_from_backend (settings, key: &skey, FALSE, TRUE);
1323
1324 if (value == NULL)
1325 value = g_settings_schema_key_get_default_value (key: &skey);
1326
1327 g_settings_schema_key_clear (key: &skey);
1328
1329 return value;
1330}
1331
1332/**
1333 * g_settings_get_enum:
1334 * @settings: a #GSettings object
1335 * @key: the key to get the value for
1336 *
1337 * Gets the value that is stored in @settings for @key and converts it
1338 * to the enum value that it represents.
1339 *
1340 * In order to use this function the type of the value must be a string
1341 * and it must be marked in the schema file as an enumerated type.
1342 *
1343 * It is a programmer error to give a @key that isn't contained in the
1344 * schema for @settings or is not marked as an enumerated type.
1345 *
1346 * If the value stored in the configuration database is not a valid
1347 * value for the enumerated type then this function will return the
1348 * default value.
1349 *
1350 * Returns: the enum value
1351 *
1352 * Since: 2.26
1353 **/
1354gint
1355g_settings_get_enum (GSettings *settings,
1356 const gchar *key)
1357{
1358 GSettingsSchemaKey skey;
1359 GVariant *value;
1360 gint result;
1361
1362 g_return_val_if_fail (G_IS_SETTINGS (settings), -1);
1363 g_return_val_if_fail (key != NULL, -1);
1364
1365 g_settings_schema_key_init (key: &skey, schema: settings->priv->schema, name: key);
1366
1367 if (!skey.is_enum)
1368 {
1369 g_critical ("g_settings_get_enum() called on key '%s' which is not "
1370 "associated with an enumerated type", skey.name);
1371 g_settings_schema_key_clear (key: &skey);
1372 return -1;
1373 }
1374
1375 value = g_settings_read_from_backend (settings, key: &skey, FALSE, FALSE);
1376
1377 if (value == NULL)
1378 value = g_settings_schema_key_get_default_value (key: &skey);
1379
1380 result = g_settings_schema_key_to_enum (key: &skey, value);
1381 g_settings_schema_key_clear (key: &skey);
1382 g_variant_unref (value);
1383
1384 return result;
1385}
1386
1387/**
1388 * g_settings_set_enum:
1389 * @settings: a #GSettings object
1390 * @key: a key, within @settings
1391 * @value: an enumerated value
1392 *
1393 * Looks up the enumerated type nick for @value and writes it to @key,
1394 * within @settings.
1395 *
1396 * It is a programmer error to give a @key that isn't contained in the
1397 * schema for @settings or is not marked as an enumerated type, or for
1398 * @value not to be a valid value for the named type.
1399 *
1400 * After performing the write, accessing @key directly with
1401 * g_settings_get_string() will return the 'nick' associated with
1402 * @value.
1403 *
1404 * Returns: %TRUE, if the set succeeds
1405 **/
1406gboolean
1407g_settings_set_enum (GSettings *settings,
1408 const gchar *key,
1409 gint value)
1410{
1411 GSettingsSchemaKey skey;
1412 GVariant *variant;
1413 gboolean success;
1414
1415 g_return_val_if_fail (G_IS_SETTINGS (settings), FALSE);
1416 g_return_val_if_fail (key != NULL, FALSE);
1417
1418 g_settings_schema_key_init (key: &skey, schema: settings->priv->schema, name: key);
1419
1420 if (!skey.is_enum)
1421 {
1422 g_critical ("g_settings_set_enum() called on key '%s' which is not "
1423 "associated with an enumerated type", skey.name);
1424 return FALSE;
1425 }
1426
1427 if (!(variant = g_settings_schema_key_from_enum (key: &skey, value)))
1428 {
1429 g_critical ("g_settings_set_enum(): invalid enum value %d for key '%s' "
1430 "in schema '%s'. Doing nothing.", value, skey.name,
1431 g_settings_schema_get_id (skey.schema));
1432 g_settings_schema_key_clear (key: &skey);
1433 return FALSE;
1434 }
1435
1436 success = g_settings_write_to_backend (settings, key: &skey, g_steal_pointer (&variant));
1437 g_settings_schema_key_clear (key: &skey);
1438
1439 return success;
1440}
1441
1442/**
1443 * g_settings_get_flags:
1444 * @settings: a #GSettings object
1445 * @key: the key to get the value for
1446 *
1447 * Gets the value that is stored in @settings for @key and converts it
1448 * to the flags value that it represents.
1449 *
1450 * In order to use this function the type of the value must be an array
1451 * of strings and it must be marked in the schema file as a flags type.
1452 *
1453 * It is a programmer error to give a @key that isn't contained in the
1454 * schema for @settings or is not marked as a flags type.
1455 *
1456 * If the value stored in the configuration database is not a valid
1457 * value for the flags type then this function will return the default
1458 * value.
1459 *
1460 * Returns: the flags value
1461 *
1462 * Since: 2.26
1463 **/
1464guint
1465g_settings_get_flags (GSettings *settings,
1466 const gchar *key)
1467{
1468 GSettingsSchemaKey skey;
1469 GVariant *value;
1470 guint result;
1471
1472 g_return_val_if_fail (G_IS_SETTINGS (settings), -1);
1473 g_return_val_if_fail (key != NULL, -1);
1474
1475 g_settings_schema_key_init (key: &skey, schema: settings->priv->schema, name: key);
1476
1477 if (!skey.is_flags)
1478 {
1479 g_critical ("g_settings_get_flags() called on key '%s' which is not "
1480 "associated with a flags type", skey.name);
1481 g_settings_schema_key_clear (key: &skey);
1482 return -1;
1483 }
1484
1485 value = g_settings_read_from_backend (settings, key: &skey, FALSE, FALSE);
1486
1487 if (value == NULL)
1488 value = g_settings_schema_key_get_default_value (key: &skey);
1489
1490 result = g_settings_schema_key_to_flags (key: &skey, value);
1491 g_settings_schema_key_clear (key: &skey);
1492 g_variant_unref (value);
1493
1494 return result;
1495}
1496
1497/**
1498 * g_settings_set_flags:
1499 * @settings: a #GSettings object
1500 * @key: a key, within @settings
1501 * @value: a flags value
1502 *
1503 * Looks up the flags type nicks for the bits specified by @value, puts
1504 * them in an array of strings and writes the array to @key, within
1505 * @settings.
1506 *
1507 * It is a programmer error to give a @key that isn't contained in the
1508 * schema for @settings or is not marked as a flags type, or for @value
1509 * to contain any bits that are not value for the named type.
1510 *
1511 * After performing the write, accessing @key directly with
1512 * g_settings_get_strv() will return an array of 'nicks'; one for each
1513 * bit in @value.
1514 *
1515 * Returns: %TRUE, if the set succeeds
1516 **/
1517gboolean
1518g_settings_set_flags (GSettings *settings,
1519 const gchar *key,
1520 guint value)
1521{
1522 GSettingsSchemaKey skey;
1523 GVariant *variant;
1524 gboolean success;
1525
1526 g_return_val_if_fail (G_IS_SETTINGS (settings), FALSE);
1527 g_return_val_if_fail (key != NULL, FALSE);
1528
1529 g_settings_schema_key_init (key: &skey, schema: settings->priv->schema, name: key);
1530
1531 if (!skey.is_flags)
1532 {
1533 g_critical ("g_settings_set_flags() called on key '%s' which is not "
1534 "associated with a flags type", skey.name);
1535 return FALSE;
1536 }
1537
1538 if (!(variant = g_settings_schema_key_from_flags (key: &skey, value)))
1539 {
1540 g_critical ("g_settings_set_flags(): invalid flags value 0x%08x "
1541 "for key '%s' in schema '%s'. Doing nothing.",
1542 value, skey.name, g_settings_schema_get_id (skey.schema));
1543 g_settings_schema_key_clear (key: &skey);
1544 return FALSE;
1545 }
1546
1547 success = g_settings_write_to_backend (settings, key: &skey, g_steal_pointer (&variant));
1548 g_settings_schema_key_clear (key: &skey);
1549
1550 return success;
1551}
1552
1553/**
1554 * g_settings_set_value:
1555 * @settings: a #GSettings object
1556 * @key: the name of the key to set
1557 * @value: a #GVariant of the correct type
1558 *
1559 * Sets @key in @settings to @value.
1560 *
1561 * It is a programmer error to give a @key that isn't contained in the
1562 * schema for @settings or for @value to have the incorrect type, per
1563 * the schema.
1564 *
1565 * If @value is floating then this function consumes the reference.
1566 *
1567 * Returns: %TRUE if setting the key succeeded,
1568 * %FALSE if the key was not writable
1569 *
1570 * Since: 2.26
1571 **/
1572gboolean
1573g_settings_set_value (GSettings *settings,
1574 const gchar *key,
1575 GVariant *value)
1576{
1577 GSettingsSchemaKey skey;
1578 gboolean success;
1579
1580 g_return_val_if_fail (G_IS_SETTINGS (settings), FALSE);
1581 g_return_val_if_fail (key != NULL, FALSE);
1582
1583 g_variant_ref_sink (value);
1584 g_settings_schema_key_init (key: &skey, schema: settings->priv->schema, name: key);
1585
1586 if (!g_settings_schema_key_type_check (key: &skey, value))
1587 {
1588 g_critical ("g_settings_set_value: key '%s' in '%s' expects type '%s', but a GVariant of type '%s' was given",
1589 key,
1590 g_settings_schema_get_id (settings->priv->schema),
1591 g_variant_type_peek_string (skey.type),
1592 g_variant_get_type_string (value));
1593 success = FALSE;
1594 }
1595 else if (!g_settings_schema_key_range_check (key: &skey, value))
1596 {
1597 g_warning ("g_settings_set_value: value for key '%s' in schema '%s' "
1598 "is outside of valid range",
1599 key,
1600 g_settings_schema_get_id (settings->priv->schema));
1601 success = FALSE;
1602 }
1603 else
1604 {
1605 success = g_settings_write_to_backend (settings, key: &skey, value);
1606 }
1607
1608 g_settings_schema_key_clear (key: &skey);
1609 g_variant_unref (value);
1610
1611 return success;
1612}
1613
1614/**
1615 * g_settings_get:
1616 * @settings: a #GSettings object
1617 * @key: the key to get the value for
1618 * @format: a #GVariant format string
1619 * @...: arguments as per @format
1620 *
1621 * Gets the value that is stored at @key in @settings.
1622 *
1623 * A convenience function that combines g_settings_get_value() with
1624 * g_variant_get().
1625 *
1626 * It is a programmer error to give a @key that isn't contained in the
1627 * schema for @settings or for the #GVariantType of @format to mismatch
1628 * the type given in the schema.
1629 *
1630 * Since: 2.26
1631 */
1632void
1633g_settings_get (GSettings *settings,
1634 const gchar *key,
1635 const gchar *format,
1636 ...)
1637{
1638 GVariant *value;
1639 va_list ap;
1640
1641 value = g_settings_get_value (settings, key);
1642
1643 if (strchr (s: format, c: '&'))
1644 {
1645 g_critical ("%s: the format string may not contain '&' (key '%s' from schema '%s'). "
1646 "This call will probably stop working with a future version of glib.",
1647 G_STRFUNC, key, g_settings_schema_get_id (settings->priv->schema));
1648 }
1649
1650 va_start (ap, format);
1651 g_variant_get_va (value, format_string: format, NULL, app: &ap);
1652 va_end (ap);
1653
1654 g_variant_unref (value);
1655}
1656
1657/**
1658 * g_settings_set:
1659 * @settings: a #GSettings object
1660 * @key: the name of the key to set
1661 * @format: a #GVariant format string
1662 * @...: arguments as per @format
1663 *
1664 * Sets @key in @settings to @value.
1665 *
1666 * A convenience function that combines g_settings_set_value() with
1667 * g_variant_new().
1668 *
1669 * It is a programmer error to give a @key that isn't contained in the
1670 * schema for @settings or for the #GVariantType of @format to mismatch
1671 * the type given in the schema.
1672 *
1673 * Returns: %TRUE if setting the key succeeded,
1674 * %FALSE if the key was not writable
1675 *
1676 * Since: 2.26
1677 */
1678gboolean
1679g_settings_set (GSettings *settings,
1680 const gchar *key,
1681 const gchar *format,
1682 ...)
1683{
1684 GVariant *value;
1685 va_list ap;
1686
1687 va_start (ap, format);
1688 value = g_variant_new_va (format_string: format, NULL, app: &ap);
1689 va_end (ap);
1690
1691 return g_settings_set_value (settings, key, g_steal_pointer (&value));
1692}
1693
1694/**
1695 * g_settings_get_mapped:
1696 * @settings: a #GSettings object
1697 * @key: the key to get the value for
1698 * @mapping: (scope call): the function to map the value in the
1699 * settings database to the value used by the application
1700 * @user_data: user data for @mapping
1701 *
1702 * Gets the value that is stored at @key in @settings, subject to
1703 * application-level validation/mapping.
1704 *
1705 * You should use this function when the application needs to perform
1706 * some processing on the value of the key (for example, parsing). The
1707 * @mapping function performs that processing. If the function
1708 * indicates that the processing was unsuccessful (due to a parse error,
1709 * for example) then the mapping is tried again with another value.
1710 *
1711 * This allows a robust 'fall back to defaults' behaviour to be
1712 * implemented somewhat automatically.
1713 *
1714 * The first value that is tried is the user's setting for the key. If
1715 * the mapping function fails to map this value, other values may be
1716 * tried in an unspecified order (system or site defaults, translated
1717 * schema default values, untranslated schema default values, etc).
1718 *
1719 * If the mapping function fails for all possible values, one additional
1720 * attempt is made: the mapping function is called with a %NULL value.
1721 * If the mapping function still indicates failure at this point then
1722 * the application will be aborted.
1723 *
1724 * The result parameter for the @mapping function is pointed to a
1725 * #gpointer which is initially set to %NULL. The same pointer is given
1726 * to each invocation of @mapping. The final value of that #gpointer is
1727 * what is returned by this function. %NULL is valid; it is returned
1728 * just as any other value would be.
1729 *
1730 * Returns: (transfer full): the result, which may be %NULL
1731 **/
1732gpointer
1733g_settings_get_mapped (GSettings *settings,
1734 const gchar *key,
1735 GSettingsGetMapping mapping,
1736 gpointer user_data)
1737{
1738 gpointer result = NULL;
1739 GSettingsSchemaKey skey;
1740 GVariant *value;
1741 gboolean okay;
1742
1743 g_return_val_if_fail (G_IS_SETTINGS (settings), NULL);
1744 g_return_val_if_fail (key != NULL, NULL);
1745 g_return_val_if_fail (mapping != NULL, NULL);
1746
1747 g_settings_schema_key_init (key: &skey, schema: settings->priv->schema, name: key);
1748
1749 if ((value = g_settings_read_from_backend (settings, key: &skey, FALSE, FALSE)))
1750 {
1751 okay = mapping (value, &result, user_data);
1752 g_variant_unref (value);
1753 if (okay) goto okay;
1754 }
1755
1756 if ((value = g_settings_schema_key_get_translated_default (key: &skey)))
1757 {
1758 okay = mapping (value, &result, user_data);
1759 g_variant_unref (value);
1760 if (okay) goto okay;
1761 }
1762
1763 if ((value = g_settings_schema_key_get_per_desktop_default (key: &skey)))
1764 {
1765 okay = mapping (value, &result, user_data);
1766 g_variant_unref (value);
1767 if (okay) goto okay;
1768 }
1769
1770 if (mapping (skey.default_value, &result, user_data))
1771 goto okay;
1772
1773 if (!mapping (NULL, &result, user_data))
1774 g_error ("The mapping function given to g_settings_get_mapped() for key "
1775 "'%s' in schema '%s' returned FALSE when given a NULL value.",
1776 key, g_settings_schema_get_id (settings->priv->schema));
1777
1778 okay:
1779 g_settings_schema_key_clear (key: &skey);
1780
1781 return result;
1782}
1783
1784/* Convenience API (get, set_string, int, double, boolean, strv) {{{1 */
1785/**
1786 * g_settings_get_string:
1787 * @settings: a #GSettings object
1788 * @key: the key to get the value for
1789 *
1790 * Gets the value that is stored at @key in @settings.
1791 *
1792 * A convenience variant of g_settings_get() for strings.
1793 *
1794 * It is a programmer error to give a @key that isn't specified as
1795 * having a string type in the schema for @settings.
1796 *
1797 * Returns: a newly-allocated string
1798 *
1799 * Since: 2.26
1800 */
1801gchar *
1802g_settings_get_string (GSettings *settings,
1803 const gchar *key)
1804{
1805 GVariant *value;
1806 gchar *result;
1807
1808 value = g_settings_get_value (settings, key);
1809 result = g_variant_dup_string (value, NULL);
1810 g_variant_unref (value);
1811
1812 return result;
1813}
1814
1815/**
1816 * g_settings_set_string:
1817 * @settings: a #GSettings object
1818 * @key: the name of the key to set
1819 * @value: the value to set it to
1820 *
1821 * Sets @key in @settings to @value.
1822 *
1823 * A convenience variant of g_settings_set() for strings.
1824 *
1825 * It is a programmer error to give a @key that isn't specified as
1826 * having a string type in the schema for @settings.
1827 *
1828 * Returns: %TRUE if setting the key succeeded,
1829 * %FALSE if the key was not writable
1830 *
1831 * Since: 2.26
1832 */
1833gboolean
1834g_settings_set_string (GSettings *settings,
1835 const gchar *key,
1836 const gchar *value)
1837{
1838 return g_settings_set_value (settings, key, value: g_variant_new_string (string: value));
1839}
1840
1841/**
1842 * g_settings_get_int:
1843 * @settings: a #GSettings object
1844 * @key: the key to get the value for
1845 *
1846 * Gets the value that is stored at @key in @settings.
1847 *
1848 * A convenience variant of g_settings_get() for 32-bit integers.
1849 *
1850 * It is a programmer error to give a @key that isn't specified as
1851 * having a int32 type in the schema for @settings.
1852 *
1853 * Returns: an integer
1854 *
1855 * Since: 2.26
1856 */
1857gint
1858g_settings_get_int (GSettings *settings,
1859 const gchar *key)
1860{
1861 GVariant *value;
1862 gint result;
1863
1864 value = g_settings_get_value (settings, key);
1865 result = g_variant_get_int32 (value);
1866 g_variant_unref (value);
1867
1868 return result;
1869}
1870
1871/**
1872 * g_settings_set_int:
1873 * @settings: a #GSettings object
1874 * @key: the name of the key to set
1875 * @value: the value to set it to
1876 *
1877 * Sets @key in @settings to @value.
1878 *
1879 * A convenience variant of g_settings_set() for 32-bit integers.
1880 *
1881 * It is a programmer error to give a @key that isn't specified as
1882 * having a int32 type in the schema for @settings.
1883 *
1884 * Returns: %TRUE if setting the key succeeded,
1885 * %FALSE if the key was not writable
1886 *
1887 * Since: 2.26
1888 */
1889gboolean
1890g_settings_set_int (GSettings *settings,
1891 const gchar *key,
1892 gint value)
1893{
1894 return g_settings_set_value (settings, key, value: g_variant_new_int32 (value));
1895}
1896
1897/**
1898 * g_settings_get_int64:
1899 * @settings: a #GSettings object
1900 * @key: the key to get the value for
1901 *
1902 * Gets the value that is stored at @key in @settings.
1903 *
1904 * A convenience variant of g_settings_get() for 64-bit integers.
1905 *
1906 * It is a programmer error to give a @key that isn't specified as
1907 * having a int64 type in the schema for @settings.
1908 *
1909 * Returns: a 64-bit integer
1910 *
1911 * Since: 2.50
1912 */
1913gint64
1914g_settings_get_int64 (GSettings *settings,
1915 const gchar *key)
1916{
1917 GVariant *value;
1918 gint64 result;
1919
1920 value = g_settings_get_value (settings, key);
1921 result = g_variant_get_int64 (value);
1922 g_variant_unref (value);
1923
1924 return result;
1925}
1926
1927/**
1928 * g_settings_set_int64:
1929 * @settings: a #GSettings object
1930 * @key: the name of the key to set
1931 * @value: the value to set it to
1932 *
1933 * Sets @key in @settings to @value.
1934 *
1935 * A convenience variant of g_settings_set() for 64-bit integers.
1936 *
1937 * It is a programmer error to give a @key that isn't specified as
1938 * having a int64 type in the schema for @settings.
1939 *
1940 * Returns: %TRUE if setting the key succeeded,
1941 * %FALSE if the key was not writable
1942 *
1943 * Since: 2.50
1944 */
1945gboolean
1946g_settings_set_int64 (GSettings *settings,
1947 const gchar *key,
1948 gint64 value)
1949{
1950 return g_settings_set_value (settings, key, value: g_variant_new_int64 (value));
1951}
1952
1953/**
1954 * g_settings_get_uint:
1955 * @settings: a #GSettings object
1956 * @key: the key to get the value for
1957 *
1958 * Gets the value that is stored at @key in @settings.
1959 *
1960 * A convenience variant of g_settings_get() for 32-bit unsigned
1961 * integers.
1962 *
1963 * It is a programmer error to give a @key that isn't specified as
1964 * having a uint32 type in the schema for @settings.
1965 *
1966 * Returns: an unsigned integer
1967 *
1968 * Since: 2.30
1969 */
1970guint
1971g_settings_get_uint (GSettings *settings,
1972 const gchar *key)
1973{
1974 GVariant *value;
1975 guint result;
1976
1977 value = g_settings_get_value (settings, key);
1978 result = g_variant_get_uint32 (value);
1979 g_variant_unref (value);
1980
1981 return result;
1982}
1983
1984/**
1985 * g_settings_set_uint:
1986 * @settings: a #GSettings object
1987 * @key: the name of the key to set
1988 * @value: the value to set it to
1989 *
1990 * Sets @key in @settings to @value.
1991 *
1992 * A convenience variant of g_settings_set() for 32-bit unsigned
1993 * integers.
1994 *
1995 * It is a programmer error to give a @key that isn't specified as
1996 * having a uint32 type in the schema for @settings.
1997 *
1998 * Returns: %TRUE if setting the key succeeded,
1999 * %FALSE if the key was not writable
2000 *
2001 * Since: 2.30
2002 */
2003gboolean
2004g_settings_set_uint (GSettings *settings,
2005 const gchar *key,
2006 guint value)
2007{
2008 return g_settings_set_value (settings, key, value: g_variant_new_uint32 (value));
2009}
2010
2011/**
2012 * g_settings_get_uint64:
2013 * @settings: a #GSettings object
2014 * @key: the key to get the value for
2015 *
2016 * Gets the value that is stored at @key in @settings.
2017 *
2018 * A convenience variant of g_settings_get() for 64-bit unsigned
2019 * integers.
2020 *
2021 * It is a programmer error to give a @key that isn't specified as
2022 * having a uint64 type in the schema for @settings.
2023 *
2024 * Returns: a 64-bit unsigned integer
2025 *
2026 * Since: 2.50
2027 */
2028guint64
2029g_settings_get_uint64 (GSettings *settings,
2030 const gchar *key)
2031{
2032 GVariant *value;
2033 guint64 result;
2034
2035 value = g_settings_get_value (settings, key);
2036 result = g_variant_get_uint64 (value);
2037 g_variant_unref (value);
2038
2039 return result;
2040}
2041
2042/**
2043 * g_settings_set_uint64:
2044 * @settings: a #GSettings object
2045 * @key: the name of the key to set
2046 * @value: the value to set it to
2047 *
2048 * Sets @key in @settings to @value.
2049 *
2050 * A convenience variant of g_settings_set() for 64-bit unsigned
2051 * integers.
2052 *
2053 * It is a programmer error to give a @key that isn't specified as
2054 * having a uint64 type in the schema for @settings.
2055 *
2056 * Returns: %TRUE if setting the key succeeded,
2057 * %FALSE if the key was not writable
2058 *
2059 * Since: 2.50
2060 */
2061gboolean
2062g_settings_set_uint64 (GSettings *settings,
2063 const gchar *key,
2064 guint64 value)
2065{
2066 return g_settings_set_value (settings, key, value: g_variant_new_uint64 (value));
2067}
2068
2069/**
2070 * g_settings_get_double:
2071 * @settings: a #GSettings object
2072 * @key: the key to get the value for
2073 *
2074 * Gets the value that is stored at @key in @settings.
2075 *
2076 * A convenience variant of g_settings_get() for doubles.
2077 *
2078 * It is a programmer error to give a @key that isn't specified as
2079 * having a 'double' type in the schema for @settings.
2080 *
2081 * Returns: a double
2082 *
2083 * Since: 2.26
2084 */
2085gdouble
2086g_settings_get_double (GSettings *settings,
2087 const gchar *key)
2088{
2089 GVariant *value;
2090 gdouble result;
2091
2092 value = g_settings_get_value (settings, key);
2093 result = g_variant_get_double (value);
2094 g_variant_unref (value);
2095
2096 return result;
2097}
2098
2099/**
2100 * g_settings_set_double:
2101 * @settings: a #GSettings object
2102 * @key: the name of the key to set
2103 * @value: the value to set it to
2104 *
2105 * Sets @key in @settings to @value.
2106 *
2107 * A convenience variant of g_settings_set() for doubles.
2108 *
2109 * It is a programmer error to give a @key that isn't specified as
2110 * having a 'double' type in the schema for @settings.
2111 *
2112 * Returns: %TRUE if setting the key succeeded,
2113 * %FALSE if the key was not writable
2114 *
2115 * Since: 2.26
2116 */
2117gboolean
2118g_settings_set_double (GSettings *settings,
2119 const gchar *key,
2120 gdouble value)
2121{
2122 return g_settings_set_value (settings, key, value: g_variant_new_double (value));
2123}
2124
2125/**
2126 * g_settings_get_boolean:
2127 * @settings: a #GSettings object
2128 * @key: the key to get the value for
2129 *
2130 * Gets the value that is stored at @key in @settings.
2131 *
2132 * A convenience variant of g_settings_get() for booleans.
2133 *
2134 * It is a programmer error to give a @key that isn't specified as
2135 * having a boolean type in the schema for @settings.
2136 *
2137 * Returns: a boolean
2138 *
2139 * Since: 2.26
2140 */
2141gboolean
2142g_settings_get_boolean (GSettings *settings,
2143 const gchar *key)
2144{
2145 GVariant *value;
2146 gboolean result;
2147
2148 value = g_settings_get_value (settings, key);
2149 result = g_variant_get_boolean (value);
2150 g_variant_unref (value);
2151
2152 return result;
2153}
2154
2155/**
2156 * g_settings_set_boolean:
2157 * @settings: a #GSettings object
2158 * @key: the name of the key to set
2159 * @value: the value to set it to
2160 *
2161 * Sets @key in @settings to @value.
2162 *
2163 * A convenience variant of g_settings_set() for booleans.
2164 *
2165 * It is a programmer error to give a @key that isn't specified as
2166 * having a boolean type in the schema for @settings.
2167 *
2168 * Returns: %TRUE if setting the key succeeded,
2169 * %FALSE if the key was not writable
2170 *
2171 * Since: 2.26
2172 */
2173gboolean
2174g_settings_set_boolean (GSettings *settings,
2175 const gchar *key,
2176 gboolean value)
2177{
2178 return g_settings_set_value (settings, key, value: g_variant_new_boolean (value));
2179}
2180
2181/**
2182 * g_settings_get_strv:
2183 * @settings: a #GSettings object
2184 * @key: the key to get the value for
2185 *
2186 * A convenience variant of g_settings_get() for string arrays.
2187 *
2188 * It is a programmer error to give a @key that isn't specified as
2189 * having an array of strings type in the schema for @settings.
2190 *
2191 * Returns: (array zero-terminated=1) (transfer full): a
2192 * newly-allocated, %NULL-terminated array of strings, the value that
2193 * is stored at @key in @settings.
2194 *
2195 * Since: 2.26
2196 */
2197gchar **
2198g_settings_get_strv (GSettings *settings,
2199 const gchar *key)
2200{
2201 GVariant *value;
2202 gchar **result;
2203
2204 value = g_settings_get_value (settings, key);
2205 result = g_variant_dup_strv (value, NULL);
2206 g_variant_unref (value);
2207
2208 return result;
2209}
2210
2211/**
2212 * g_settings_set_strv:
2213 * @settings: a #GSettings object
2214 * @key: the name of the key to set
2215 * @value: (nullable) (array zero-terminated=1): the value to set it to, or %NULL
2216 *
2217 * Sets @key in @settings to @value.
2218 *
2219 * A convenience variant of g_settings_set() for string arrays. If
2220 * @value is %NULL, then @key is set to be the empty array.
2221 *
2222 * It is a programmer error to give a @key that isn't specified as
2223 * having an array of strings type in the schema for @settings.
2224 *
2225 * Returns: %TRUE if setting the key succeeded,
2226 * %FALSE if the key was not writable
2227 *
2228 * Since: 2.26
2229 */
2230gboolean
2231g_settings_set_strv (GSettings *settings,
2232 const gchar *key,
2233 const gchar * const *value)
2234{
2235 GVariant *array;
2236
2237 if (value != NULL)
2238 array = g_variant_new_strv (strv: value, length: -1);
2239 else
2240 array = g_variant_new_strv (NULL, length: 0);
2241
2242 return g_settings_set_value (settings, key, value: array);
2243}
2244
2245/* Delayed apply (delay, apply, revert, get_has_unapplied) {{{1 */
2246/**
2247 * g_settings_delay:
2248 * @settings: a #GSettings object
2249 *
2250 * Changes the #GSettings object into 'delay-apply' mode. In this
2251 * mode, changes to @settings are not immediately propagated to the
2252 * backend, but kept locally until g_settings_apply() is called.
2253 *
2254 * Since: 2.26
2255 */
2256void
2257g_settings_delay (GSettings *settings)
2258{
2259 g_return_if_fail (G_IS_SETTINGS (settings));
2260
2261 if (settings->priv->delayed)
2262 return;
2263
2264 settings->priv->delayed =
2265 g_delayed_settings_backend_new (backend: settings->priv->backend,
2266 owner: settings,
2267 owner_context: settings->priv->main_context);
2268 g_settings_backend_unwatch (backend: settings->priv->backend, G_OBJECT (settings));
2269 g_object_unref (object: settings->priv->backend);
2270
2271 settings->priv->backend = G_SETTINGS_BACKEND (settings->priv->delayed);
2272 g_settings_backend_watch (backend: settings->priv->backend,
2273 vtable: &listener_vtable, G_OBJECT (settings),
2274 context: settings->priv->main_context);
2275
2276 g_object_notify (G_OBJECT (settings), property_name: "delay-apply");
2277}
2278
2279/**
2280 * g_settings_apply:
2281 * @settings: a #GSettings instance
2282 *
2283 * Applies any changes that have been made to the settings. This
2284 * function does nothing unless @settings is in 'delay-apply' mode;
2285 * see g_settings_delay(). In the normal case settings are always
2286 * applied immediately.
2287 **/
2288void
2289g_settings_apply (GSettings *settings)
2290{
2291 if (settings->priv->delayed)
2292 {
2293 GDelayedSettingsBackend *delayed;
2294
2295 delayed = G_DELAYED_SETTINGS_BACKEND (settings->priv->backend);
2296 g_delayed_settings_backend_apply (delayed);
2297 }
2298}
2299
2300/**
2301 * g_settings_revert:
2302 * @settings: a #GSettings instance
2303 *
2304 * Reverts all non-applied changes to the settings. This function
2305 * does nothing unless @settings is in 'delay-apply' mode; see
2306 * g_settings_delay(). In the normal case settings are always applied
2307 * immediately.
2308 *
2309 * Change notifications will be emitted for affected keys.
2310 **/
2311void
2312g_settings_revert (GSettings *settings)
2313{
2314 if (settings->priv->delayed)
2315 {
2316 GDelayedSettingsBackend *delayed;
2317
2318 delayed = G_DELAYED_SETTINGS_BACKEND (settings->priv->backend);
2319 g_delayed_settings_backend_revert (delayed);
2320 }
2321}
2322
2323/**
2324 * g_settings_get_has_unapplied:
2325 * @settings: a #GSettings object
2326 *
2327 * Returns whether the #GSettings object has any unapplied
2328 * changes. This can only be the case if it is in 'delayed-apply' mode.
2329 *
2330 * Returns: %TRUE if @settings has unapplied changes
2331 *
2332 * Since: 2.26
2333 */
2334gboolean
2335g_settings_get_has_unapplied (GSettings *settings)
2336{
2337 g_return_val_if_fail (G_IS_SETTINGS (settings), FALSE);
2338
2339 return settings->priv->delayed &&
2340 g_delayed_settings_backend_get_has_unapplied (
2341 G_DELAYED_SETTINGS_BACKEND (settings->priv->backend));
2342}
2343
2344/* Extra API (reset, sync, get_child, is_writable, list_*, ranges) {{{1 */
2345/**
2346 * g_settings_reset:
2347 * @settings: a #GSettings object
2348 * @key: the name of a key
2349 *
2350 * Resets @key to its default value.
2351 *
2352 * This call resets the key, as much as possible, to its default value.
2353 * That might be the value specified in the schema or the one set by the
2354 * administrator.
2355 **/
2356void
2357g_settings_reset (GSettings *settings,
2358 const gchar *key)
2359{
2360 gchar *path;
2361
2362 g_return_if_fail (G_IS_SETTINGS (settings));
2363 g_return_if_fail (key != NULL);
2364
2365 path = g_strconcat (string1: settings->priv->path, key, NULL);
2366 g_settings_backend_reset (backend: settings->priv->backend, key: path, NULL);
2367 g_free (mem: path);
2368}
2369
2370/**
2371 * g_settings_sync:
2372 *
2373 * Ensures that all pending operations are complete for the default backend.
2374 *
2375 * Writes made to a #GSettings are handled asynchronously. For this
2376 * reason, it is very unlikely that the changes have it to disk by the
2377 * time g_settings_set() returns.
2378 *
2379 * This call will block until all of the writes have made it to the
2380 * backend. Since the mainloop is not running, no change notifications
2381 * will be dispatched during this call (but some may be queued by the
2382 * time the call is done).
2383 **/
2384void
2385g_settings_sync (void)
2386{
2387 g_settings_backend_sync_default ();
2388}
2389
2390/**
2391 * g_settings_is_writable:
2392 * @settings: a #GSettings object
2393 * @name: the name of a key
2394 *
2395 * Finds out if a key can be written or not
2396 *
2397 * Returns: %TRUE if the key @name is writable
2398 *
2399 * Since: 2.26
2400 */
2401gboolean
2402g_settings_is_writable (GSettings *settings,
2403 const gchar *name)
2404{
2405 gboolean writable;
2406 gchar *path;
2407
2408 g_return_val_if_fail (G_IS_SETTINGS (settings), FALSE);
2409
2410 path = g_strconcat (string1: settings->priv->path, name, NULL);
2411 writable = g_settings_backend_get_writable (backend: settings->priv->backend, key: path);
2412 g_free (mem: path);
2413
2414 return writable;
2415}
2416
2417/**
2418 * g_settings_get_child:
2419 * @settings: a #GSettings object
2420 * @name: the name of the child schema
2421 *
2422 * Creates a child settings object which has a base path of
2423 * `base-path/@name`, where `base-path` is the base path of
2424 * @settings.
2425 *
2426 * The schema for the child settings object must have been declared
2427 * in the schema of @settings using a <child> element.
2428 *
2429 * Returns: (transfer full): a 'child' settings object
2430 *
2431 * Since: 2.26
2432 */
2433GSettings *
2434g_settings_get_child (GSettings *settings,
2435 const gchar *name)
2436{
2437 const gchar *child_schema;
2438 gchar *child_path;
2439 gchar *child_name;
2440 GSettings *child;
2441
2442 g_return_val_if_fail (G_IS_SETTINGS (settings), NULL);
2443
2444 child_name = g_strconcat (string1: name, "/", NULL);
2445 child_schema = g_settings_schema_get_string (schema: settings->priv->schema,
2446 key: child_name);
2447 if (child_schema == NULL)
2448 g_error ("Schema '%s' has no child '%s'",
2449 g_settings_schema_get_id (settings->priv->schema), name);
2450
2451 child_path = g_strconcat (string1: settings->priv->path, child_name, NULL);
2452 child = g_object_new (G_TYPE_SETTINGS,
2453 first_property_name: "backend", settings->priv->backend,
2454 "schema-id", child_schema,
2455 "path", child_path,
2456 NULL);
2457 g_free (mem: child_path);
2458 g_free (mem: child_name);
2459
2460 return child;
2461}
2462
2463/**
2464 * g_settings_list_keys:
2465 * @settings: a #GSettings object
2466 *
2467 * Introspects the list of keys on @settings.
2468 *
2469 * You should probably not be calling this function from "normal" code
2470 * (since you should already know what keys are in your schema). This
2471 * function is intended for introspection reasons.
2472 *
2473 * You should free the return value with g_strfreev() when you are done
2474 * with it.
2475 *
2476 * Returns: (transfer full) (element-type utf8): a list of the keys on
2477 * @settings, in no defined order
2478 * Deprecated: 2.46: Use g_settings_schema_list_keys() instead.
2479 */
2480gchar **
2481g_settings_list_keys (GSettings *settings)
2482{
2483 return g_settings_schema_list_keys (schema: settings->priv->schema);
2484}
2485
2486/**
2487 * g_settings_list_children:
2488 * @settings: a #GSettings object
2489 *
2490 * Gets the list of children on @settings.
2491 *
2492 * The list is exactly the list of strings for which it is not an error
2493 * to call g_settings_get_child().
2494 *
2495 * There is little reason to call this function from "normal" code, since
2496 * you should already know what children are in your schema. This function
2497 * may still be useful there for introspection reasons, however.
2498 *
2499 * You should free the return value with g_strfreev() when you are done
2500 * with it.
2501 *
2502 * Returns: (transfer full) (element-type utf8): a list of the children on
2503 * @settings, in no defined order
2504 */
2505gchar **
2506g_settings_list_children (GSettings *settings)
2507{
2508 return g_settings_schema_list_children (schema: settings->priv->schema);
2509}
2510
2511/**
2512 * g_settings_get_range:
2513 * @settings: a #GSettings
2514 * @key: the key to query the range of
2515 *
2516 * Queries the range of a key.
2517 *
2518 * Since: 2.28
2519 *
2520 * Deprecated:2.40:Use g_settings_schema_key_get_range() instead.
2521 **/
2522GVariant *
2523g_settings_get_range (GSettings *settings,
2524 const gchar *key)
2525{
2526 GSettingsSchemaKey skey;
2527 GVariant *range;
2528
2529 g_settings_schema_key_init (key: &skey, schema: settings->priv->schema, name: key);
2530 range = g_settings_schema_key_get_range (key: &skey);
2531 g_settings_schema_key_clear (key: &skey);
2532
2533 return range;
2534}
2535
2536/**
2537 * g_settings_range_check:
2538 * @settings: a #GSettings
2539 * @key: the key to check
2540 * @value: the value to check
2541 *
2542 * Checks if the given @value is of the correct type and within the
2543 * permitted range for @key.
2544 *
2545 * Returns: %TRUE if @value is valid for @key
2546 *
2547 * Since: 2.28
2548 *
2549 * Deprecated:2.40:Use g_settings_schema_key_range_check() instead.
2550 **/
2551gboolean
2552g_settings_range_check (GSettings *settings,
2553 const gchar *key,
2554 GVariant *value)
2555{
2556 GSettingsSchemaKey skey;
2557 gboolean good;
2558
2559 g_settings_schema_key_init (key: &skey, schema: settings->priv->schema, name: key);
2560 good = g_settings_schema_key_range_check (key: &skey, value);
2561 g_settings_schema_key_clear (key: &skey);
2562
2563 return good;
2564}
2565
2566/* Binding {{{1 */
2567typedef struct
2568{
2569 GSettingsSchemaKey key;
2570 GSettings *settings;
2571 GObject *object;
2572
2573 GSettingsBindGetMapping get_mapping;
2574 GSettingsBindSetMapping set_mapping;
2575 gpointer user_data;
2576 GDestroyNotify destroy;
2577
2578 guint writable_handler_id;
2579 guint property_handler_id;
2580 const GParamSpec *property;
2581 guint key_handler_id;
2582
2583 /* prevent recursion */
2584 gboolean running;
2585} GSettingsBinding;
2586
2587static void
2588g_settings_binding_free (gpointer data)
2589{
2590 GSettingsBinding *binding = data;
2591
2592 g_assert (!binding->running);
2593
2594 if (binding->writable_handler_id)
2595 g_signal_handler_disconnect (instance: binding->settings,
2596 handler_id: binding->writable_handler_id);
2597
2598 if (binding->key_handler_id)
2599 g_signal_handler_disconnect (instance: binding->settings,
2600 handler_id: binding->key_handler_id);
2601
2602 if (g_signal_handler_is_connected (instance: binding->object,
2603 handler_id: binding->property_handler_id))
2604 g_signal_handler_disconnect (instance: binding->object,
2605 handler_id: binding->property_handler_id);
2606
2607 g_settings_schema_key_clear (key: &binding->key);
2608
2609 if (binding->destroy)
2610 binding->destroy (binding->user_data);
2611
2612 g_object_unref (object: binding->settings);
2613
2614 g_slice_free (GSettingsBinding, binding);
2615}
2616
2617static GQuark
2618g_settings_binding_quark (const char *property)
2619{
2620 GQuark quark;
2621 gchar *tmp;
2622
2623 tmp = g_strdup_printf (format: "gsettingsbinding-%s", property);
2624 quark = g_quark_from_string (string: tmp);
2625 g_free (mem: tmp);
2626
2627 return quark;
2628}
2629
2630static void
2631g_settings_binding_key_changed (GSettings *settings,
2632 const gchar *key,
2633 gpointer user_data)
2634{
2635 GSettingsBinding *binding = user_data;
2636 GValue value = G_VALUE_INIT;
2637 GVariant *variant;
2638
2639 g_assert (settings == binding->settings);
2640 g_assert (key == binding->key.name);
2641
2642 if (binding->running)
2643 return;
2644
2645 binding->running = TRUE;
2646
2647 g_value_init (value: &value, g_type: binding->property->value_type);
2648
2649 variant = g_settings_read_from_backend (settings: binding->settings, key: &binding->key, FALSE, FALSE);
2650 if (variant && !binding->get_mapping (&value, variant, binding->user_data))
2651 {
2652 /* silently ignore errors in the user's config database */
2653 g_variant_unref (value: variant);
2654 variant = NULL;
2655 }
2656
2657 if (variant == NULL)
2658 {
2659 variant = g_settings_schema_key_get_translated_default (key: &binding->key);
2660 if (variant &&
2661 !binding->get_mapping (&value, variant, binding->user_data))
2662 {
2663 /* flag translation errors with a warning */
2664 g_warning ("Translated default '%s' for key '%s' in schema '%s' "
2665 "was rejected by the binding mapping function",
2666 binding->key.unparsed, binding->key.name,
2667 g_settings_schema_get_id (binding->key.schema));
2668 g_variant_unref (value: variant);
2669 variant = NULL;
2670 }
2671 }
2672
2673 if (variant == NULL)
2674 {
2675 variant = g_settings_schema_key_get_per_desktop_default (key: &binding->key);
2676 if (variant &&
2677 !binding->get_mapping (&value, variant, binding->user_data))
2678 {
2679 g_error ("Per-desktop default value for key '%s' in schema '%s' "
2680 "was rejected by the binding mapping function.",
2681 binding->key.name, g_settings_schema_get_id (binding->key.schema));
2682 g_variant_unref (value: variant);
2683 variant = NULL;
2684 }
2685 }
2686
2687 if (variant == NULL)
2688 {
2689 variant = g_variant_ref (value: binding->key.default_value);
2690 if (!binding->get_mapping (&value, variant, binding->user_data))
2691 g_error ("The schema default value for key '%s' in schema '%s' "
2692 "was rejected by the binding mapping function.",
2693 binding->key.name, g_settings_schema_get_id (binding->key.schema));
2694 }
2695
2696 g_object_set_property (object: binding->object, property_name: binding->property->name, value: &value);
2697 g_variant_unref (value: variant);
2698 g_value_unset (value: &value);
2699
2700 binding->running = FALSE;
2701}
2702
2703static void
2704g_settings_binding_property_changed (GObject *object,
2705 const GParamSpec *pspec,
2706 gpointer user_data)
2707{
2708 GSettingsBinding *binding = user_data;
2709 GValue value = G_VALUE_INIT;
2710 GVariant *variant;
2711 gboolean valid = TRUE;
2712
2713 g_assert (object == binding->object);
2714 g_assert (pspec == binding->property);
2715
2716 if (binding->running)
2717 return;
2718
2719 binding->running = TRUE;
2720
2721 g_value_init (value: &value, g_type: pspec->value_type);
2722 g_object_get_property (object, property_name: pspec->name, value: &value);
2723 if ((variant = binding->set_mapping (&value, binding->key.type,
2724 binding->user_data)))
2725 {
2726 g_variant_take_ref (value: variant);
2727
2728 if (!g_settings_schema_key_type_check (key: &binding->key, value: variant))
2729 {
2730 gchar *type_str;
2731 type_str = g_variant_type_dup_string (type: binding->key.type);
2732 g_critical ("binding mapping function for key '%s' returned "
2733 "GVariant of type '%s' when type '%s' was requested",
2734 binding->key.name, g_variant_get_type_string (variant),
2735 type_str);
2736 g_free (mem: type_str);
2737 valid = FALSE;
2738 }
2739
2740 if (valid && !g_settings_schema_key_range_check (key: &binding->key, value: variant))
2741 {
2742 gchar *variant_str;
2743 variant_str = g_variant_print (value: variant, TRUE);
2744 g_critical ("GObject property '%s' on a '%s' object is out of "
2745 "schema-specified range for key '%s' of '%s': %s",
2746 binding->property->name, g_type_name (binding->property->owner_type),
2747 binding->key.name, g_settings_schema_get_id (binding->key.schema),
2748 variant_str);
2749 g_free (mem: variant_str);
2750 valid = FALSE;
2751 }
2752
2753 if (valid)
2754 {
2755 g_settings_write_to_backend (settings: binding->settings, key: &binding->key, value: variant);
2756 }
2757 g_variant_unref (value: variant);
2758 }
2759 g_value_unset (value: &value);
2760
2761 binding->running = FALSE;
2762}
2763
2764static gboolean
2765g_settings_bind_invert_boolean_get_mapping (GValue *value,
2766 GVariant *variant,
2767 gpointer user_data)
2768{
2769 g_value_set_boolean (value, v_boolean: !g_variant_get_boolean (value: variant));
2770 return TRUE;
2771}
2772
2773static GVariant *
2774g_settings_bind_invert_boolean_set_mapping (const GValue *value,
2775 const GVariantType *expected_type,
2776 gpointer user_data)
2777{
2778 return g_variant_new_boolean (value: !g_value_get_boolean (value));
2779}
2780
2781/**
2782 * g_settings_bind:
2783 * @settings: a #GSettings object
2784 * @key: the key to bind
2785 * @object: (type GObject.Object): a #GObject
2786 * @property: the name of the property to bind
2787 * @flags: flags for the binding
2788 *
2789 * Create a binding between the @key in the @settings object
2790 * and the property @property of @object.
2791 *
2792 * The binding uses the default GIO mapping functions to map
2793 * between the settings and property values. These functions
2794 * handle booleans, numeric types and string types in a
2795 * straightforward way. Use g_settings_bind_with_mapping() if
2796 * you need a custom mapping, or map between types that are not
2797 * supported by the default mapping functions.
2798 *
2799 * Unless the @flags include %G_SETTINGS_BIND_NO_SENSITIVITY, this
2800 * function also establishes a binding between the writability of
2801 * @key and the "sensitive" property of @object (if @object has
2802 * a boolean property by that name). See g_settings_bind_writable()
2803 * for more details about writable bindings.
2804 *
2805 * Note that the lifecycle of the binding is tied to @object,
2806 * and that you can have only one binding per object property.
2807 * If you bind the same property twice on the same object, the second
2808 * binding overrides the first one.
2809 *
2810 * Since: 2.26
2811 */
2812void
2813g_settings_bind (GSettings *settings,
2814 const gchar *key,
2815 gpointer object,
2816 const gchar *property,
2817 GSettingsBindFlags flags)
2818{
2819 GSettingsBindGetMapping get_mapping = NULL;
2820 GSettingsBindSetMapping set_mapping = NULL;
2821
2822 if (flags & G_SETTINGS_BIND_INVERT_BOOLEAN)
2823 {
2824 get_mapping = g_settings_bind_invert_boolean_get_mapping;
2825 set_mapping = g_settings_bind_invert_boolean_set_mapping;
2826
2827 /* can't pass this flag to g_settings_bind_with_mapping() */
2828 flags &= ~G_SETTINGS_BIND_INVERT_BOOLEAN;
2829 }
2830
2831 g_settings_bind_with_mapping (settings, key, object, property, flags,
2832 get_mapping, set_mapping, NULL, NULL);
2833}
2834
2835/**
2836 * g_settings_bind_with_mapping: (skip)
2837 * @settings: a #GSettings object
2838 * @key: the key to bind
2839 * @object: (type GObject.Object): a #GObject
2840 * @property: the name of the property to bind
2841 * @flags: flags for the binding
2842 * @get_mapping: a function that gets called to convert values
2843 * from @settings to @object, or %NULL to use the default GIO mapping
2844 * @set_mapping: a function that gets called to convert values
2845 * from @object to @settings, or %NULL to use the default GIO mapping
2846 * @user_data: data that gets passed to @get_mapping and @set_mapping
2847 * @destroy: #GDestroyNotify function for @user_data
2848 *
2849 * Create a binding between the @key in the @settings object
2850 * and the property @property of @object.
2851 *
2852 * The binding uses the provided mapping functions to map between
2853 * settings and property values.
2854 *
2855 * Note that the lifecycle of the binding is tied to @object,
2856 * and that you can have only one binding per object property.
2857 * If you bind the same property twice on the same object, the second
2858 * binding overrides the first one.
2859 *
2860 * Since: 2.26
2861 */
2862void
2863g_settings_bind_with_mapping (GSettings *settings,
2864 const gchar *key,
2865 gpointer object,
2866 const gchar *property,
2867 GSettingsBindFlags flags,
2868 GSettingsBindGetMapping get_mapping,
2869 GSettingsBindSetMapping set_mapping,
2870 gpointer user_data,
2871 GDestroyNotify destroy)
2872{
2873 GSettingsBinding *binding;
2874 GObjectClass *objectclass;
2875 gchar *detailed_signal;
2876 GQuark binding_quark;
2877
2878 g_return_if_fail (G_IS_SETTINGS (settings));
2879 g_return_if_fail (key != NULL);
2880 g_return_if_fail (G_IS_OBJECT (object));
2881 g_return_if_fail (property != NULL);
2882 g_return_if_fail (~flags & G_SETTINGS_BIND_INVERT_BOOLEAN);
2883
2884 objectclass = G_OBJECT_GET_CLASS (object);
2885
2886 binding = g_slice_new0 (GSettingsBinding);
2887 g_settings_schema_key_init (key: &binding->key, schema: settings->priv->schema, name: key);
2888 binding->settings = g_object_ref (settings);
2889 binding->object = object;
2890 binding->property = g_object_class_find_property (oclass: objectclass, property_name: property);
2891 binding->user_data = user_data;
2892 binding->destroy = destroy;
2893 binding->get_mapping = get_mapping ? get_mapping : g_settings_get_mapping;
2894 binding->set_mapping = set_mapping ? set_mapping : g_settings_set_mapping;
2895
2896 if (!(flags & (G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET)))
2897 flags |= G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET;
2898
2899 if (binding->property == NULL)
2900 {
2901 g_critical ("g_settings_bind: no property '%s' on class '%s'",
2902 property, G_OBJECT_TYPE_NAME (object));
2903 return;
2904 }
2905
2906 if ((flags & G_SETTINGS_BIND_GET) &&
2907 (binding->property->flags & G_PARAM_WRITABLE) == 0)
2908 {
2909 g_critical ("g_settings_bind: property '%s' on class '%s' is not "
2910 "writable", binding->property->name, G_OBJECT_TYPE_NAME (object));
2911 return;
2912 }
2913 if ((flags & G_SETTINGS_BIND_SET) &&
2914 (binding->property->flags & G_PARAM_READABLE) == 0)
2915 {
2916 g_critical ("g_settings_bind: property '%s' on class '%s' is not "
2917 "readable", binding->property->name, G_OBJECT_TYPE_NAME (object));
2918 return;
2919 }
2920
2921 if (get_mapping == g_settings_bind_invert_boolean_get_mapping)
2922 {
2923 /* g_settings_bind_invert_boolean_get_mapping() is a private
2924 * function, so if we are here it means that g_settings_bind() was
2925 * called with G_SETTINGS_BIND_INVERT_BOOLEAN.
2926 *
2927 * Ensure that both sides are boolean.
2928 */
2929
2930 if (binding->property->value_type != G_TYPE_BOOLEAN)
2931 {
2932 g_critical ("g_settings_bind: G_SETTINGS_BIND_INVERT_BOOLEAN "
2933 "was specified, but property '%s' on type '%s' has "
2934 "type '%s'", binding->property->name, G_OBJECT_TYPE_NAME (object),
2935 g_type_name ((binding->property->value_type)));
2936 return;
2937 }
2938
2939 if (!g_variant_type_equal (type1: binding->key.type, G_VARIANT_TYPE_BOOLEAN))
2940 {
2941 gchar *type_string = g_variant_type_dup_string (type: binding->key.type);
2942 g_critical ("g_settings_bind: G_SETTINGS_BIND_INVERT_BOOLEAN "
2943 "was specified, but key '%s' on schema '%s' has "
2944 "type '%s'", key, g_settings_schema_get_id (settings->priv->schema),
2945 type_string);
2946 g_free (mem: type_string);
2947 return;
2948 }
2949
2950 }
2951
2952 else if (((get_mapping == NULL && (flags & G_SETTINGS_BIND_GET)) ||
2953 (set_mapping == NULL && (flags & G_SETTINGS_BIND_SET))) &&
2954 !g_settings_mapping_is_compatible (gvalue_type: binding->property->value_type,
2955 variant_type: binding->key.type))
2956 {
2957 gchar *type_string = g_variant_type_dup_string (type: binding->key.type);
2958 g_critical ("g_settings_bind: property '%s' on class '%s' has type "
2959 "'%s' which is not compatible with type '%s' of key '%s' "
2960 "on schema '%s'", binding->property->name, G_OBJECT_TYPE_NAME (object),
2961 g_type_name (binding->property->value_type),
2962 type_string, key,
2963 g_settings_schema_get_id (settings->priv->schema));
2964 g_free (mem: type_string);
2965 return;
2966 }
2967
2968 if ((flags & G_SETTINGS_BIND_SET) &&
2969 (~flags & G_SETTINGS_BIND_NO_SENSITIVITY))
2970 {
2971 GParamSpec *sensitive;
2972
2973 sensitive = g_object_class_find_property (oclass: objectclass, property_name: "sensitive");
2974
2975 if (sensitive && sensitive->value_type == G_TYPE_BOOLEAN &&
2976 (sensitive->flags & G_PARAM_WRITABLE))
2977 g_settings_bind_writable (settings, key: binding->key.name, object, property: "sensitive", FALSE);
2978 }
2979
2980 if (flags & G_SETTINGS_BIND_SET)
2981 {
2982 detailed_signal = g_strdup_printf (format: "notify::%s", binding->property->name);
2983 binding->property_handler_id =
2984 g_signal_connect (object, detailed_signal,
2985 G_CALLBACK (g_settings_binding_property_changed),
2986 binding);
2987 g_free (mem: detailed_signal);
2988
2989 if (~flags & G_SETTINGS_BIND_GET)
2990 g_settings_binding_property_changed (object,
2991 pspec: binding->property,
2992 user_data: binding);
2993 }
2994
2995 if (flags & G_SETTINGS_BIND_GET)
2996 {
2997 if (~flags & G_SETTINGS_BIND_GET_NO_CHANGES)
2998 {
2999 detailed_signal = g_strdup_printf (format: "changed::%s", key);
3000 binding->key_handler_id =
3001 g_signal_connect (settings, detailed_signal,
3002 G_CALLBACK (g_settings_binding_key_changed),
3003 binding);
3004 g_free (mem: detailed_signal);
3005 }
3006
3007 g_settings_binding_key_changed (settings, key: binding->key.name, user_data: binding);
3008 }
3009
3010 binding_quark = g_settings_binding_quark (property: binding->property->name);
3011 g_object_set_qdata_full (object, quark: binding_quark,
3012 data: binding, destroy: g_settings_binding_free);
3013}
3014
3015/* Writability binding {{{1 */
3016typedef struct
3017{
3018 GSettings *settings;
3019 gpointer object;
3020 const gchar *key;
3021 const gchar *property;
3022 gboolean inverted;
3023 gulong handler_id;
3024} GSettingsWritableBinding;
3025
3026static void
3027g_settings_writable_binding_free (gpointer data)
3028{
3029 GSettingsWritableBinding *binding = data;
3030
3031 g_signal_handler_disconnect (instance: binding->settings, handler_id: binding->handler_id);
3032 g_object_unref (object: binding->settings);
3033 g_slice_free (GSettingsWritableBinding, binding);
3034}
3035
3036static void
3037g_settings_binding_writable_changed (GSettings *settings,
3038 const gchar *key,
3039 gpointer user_data)
3040{
3041 GSettingsWritableBinding *binding = user_data;
3042 gboolean writable;
3043
3044 g_assert (settings == binding->settings);
3045 g_assert (key == binding->key);
3046
3047 writable = g_settings_is_writable (settings, name: key);
3048
3049 if (binding->inverted)
3050 writable = !writable;
3051
3052 g_object_set (object: binding->object, first_property_name: binding->property, writable, NULL);
3053}
3054
3055/**
3056 * g_settings_bind_writable:
3057 * @settings: a #GSettings object
3058 * @key: the key to bind
3059 * @object: (type GObject.Object):a #GObject
3060 * @property: the name of a boolean property to bind
3061 * @inverted: whether to 'invert' the value
3062 *
3063 * Create a binding between the writability of @key in the
3064 * @settings object and the property @property of @object.
3065 * The property must be boolean; "sensitive" or "visible"
3066 * properties of widgets are the most likely candidates.
3067 *
3068 * Writable bindings are always uni-directional; changes of the
3069 * writability of the setting will be propagated to the object
3070 * property, not the other way.
3071 *
3072 * When the @inverted argument is %TRUE, the binding inverts the
3073 * value as it passes from the setting to the object, i.e. @property
3074 * will be set to %TRUE if the key is not writable.
3075 *
3076 * Note that the lifecycle of the binding is tied to @object,
3077 * and that you can have only one binding per object property.
3078 * If you bind the same property twice on the same object, the second
3079 * binding overrides the first one.
3080 *
3081 * Since: 2.26
3082 */
3083void
3084g_settings_bind_writable (GSettings *settings,
3085 const gchar *key,
3086 gpointer object,
3087 const gchar *property,
3088 gboolean inverted)
3089{
3090 GSettingsWritableBinding *binding;
3091 gchar *detailed_signal;
3092 GParamSpec *pspec;
3093
3094 g_return_if_fail (G_IS_SETTINGS (settings));
3095
3096 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), property_name: property);
3097 if (pspec == NULL)
3098 {
3099 g_critical ("g_settings_bind_writable: no property '%s' on class '%s'",
3100 property, G_OBJECT_TYPE_NAME (object));
3101 return;
3102 }
3103 if ((pspec->flags & G_PARAM_WRITABLE) == 0)
3104 {
3105 g_critical ("g_settings_bind_writable: property '%s' on class '%s' is not writable",
3106 property, G_OBJECT_TYPE_NAME (object));
3107 return;
3108 }
3109
3110 binding = g_slice_new (GSettingsWritableBinding);
3111 binding->settings = g_object_ref (settings);
3112 binding->object = object;
3113 binding->key = g_intern_string (string: key);
3114 binding->property = g_intern_string (string: property);
3115 binding->inverted = inverted;
3116
3117 detailed_signal = g_strdup_printf (format: "writable-changed::%s", key);
3118 binding->handler_id =
3119 g_signal_connect (settings, detailed_signal,
3120 G_CALLBACK (g_settings_binding_writable_changed),
3121 binding);
3122 g_free (mem: detailed_signal);
3123
3124 g_object_set_qdata_full (object, quark: g_settings_binding_quark (property),
3125 data: binding, destroy: g_settings_writable_binding_free);
3126
3127 g_settings_binding_writable_changed (settings, key: binding->key, user_data: binding);
3128}
3129
3130/**
3131 * g_settings_unbind:
3132 * @object: (type GObject.Object): the object
3133 * @property: the property whose binding is removed
3134 *
3135 * Removes an existing binding for @property on @object.
3136 *
3137 * Note that bindings are automatically removed when the
3138 * object is finalized, so it is rarely necessary to call this
3139 * function.
3140 *
3141 * Since: 2.26
3142 */
3143void
3144g_settings_unbind (gpointer object,
3145 const gchar *property)
3146{
3147 GQuark binding_quark;
3148
3149 binding_quark = g_settings_binding_quark (property);
3150 g_object_set_qdata (object, quark: binding_quark, NULL);
3151}
3152
3153/* GAction {{{1 */
3154
3155typedef struct
3156{
3157 GObject parent_instance;
3158
3159 GSettingsSchemaKey key;
3160 GSettings *settings;
3161} GSettingsAction;
3162
3163typedef GObjectClass GSettingsActionClass;
3164
3165static GType g_settings_action_get_type (void);
3166static void g_settings_action_iface_init (GActionInterface *iface);
3167G_DEFINE_TYPE_WITH_CODE (GSettingsAction, g_settings_action, G_TYPE_OBJECT,
3168 G_IMPLEMENT_INTERFACE (G_TYPE_ACTION, g_settings_action_iface_init))
3169
3170enum
3171{
3172 ACTION_PROP_0,
3173 ACTION_PROP_NAME,
3174 ACTION_PROP_PARAMETER_TYPE,
3175 ACTION_PROP_ENABLED,
3176 ACTION_PROP_STATE_TYPE,
3177 ACTION_PROP_STATE
3178};
3179
3180static const gchar *
3181g_settings_action_get_name (GAction *action)
3182{
3183 GSettingsAction *gsa = (GSettingsAction *) action;
3184
3185 return gsa->key.name;
3186}
3187
3188static const GVariantType *
3189g_settings_action_get_parameter_type (GAction *action)
3190{
3191 GSettingsAction *gsa = (GSettingsAction *) action;
3192 const GVariantType *type;
3193
3194 type = g_variant_get_type (value: gsa->key.default_value);
3195 if (g_variant_type_equal (type1: type, G_VARIANT_TYPE_BOOLEAN))
3196 type = NULL;
3197
3198 return type;
3199}
3200
3201static gboolean
3202g_settings_action_get_enabled (GAction *action)
3203{
3204 GSettingsAction *gsa = (GSettingsAction *) action;
3205
3206 return g_settings_is_writable (settings: gsa->settings, name: gsa->key.name);
3207}
3208
3209static const GVariantType *
3210g_settings_action_get_state_type (GAction *action)
3211{
3212 GSettingsAction *gsa = (GSettingsAction *) action;
3213
3214 return g_variant_get_type (value: gsa->key.default_value);
3215}
3216
3217static GVariant *
3218g_settings_action_get_state (GAction *action)
3219{
3220 GSettingsAction *gsa = (GSettingsAction *) action;
3221 GVariant *value;
3222
3223 value = g_settings_read_from_backend (settings: gsa->settings, key: &gsa->key, FALSE, FALSE);
3224
3225 if (value == NULL)
3226 value = g_settings_schema_key_get_translated_default (key: &gsa->key);
3227
3228 if (value == NULL)
3229 value = g_variant_ref (value: gsa->key.default_value);
3230
3231 return value;
3232}
3233
3234static GVariant *
3235g_settings_action_get_state_hint (GAction *action)
3236{
3237 GSettingsAction *gsa = (GSettingsAction *) action;
3238
3239 /* no point in reimplementing this... */
3240 return g_settings_schema_key_get_range (key: &gsa->key);
3241}
3242
3243static void
3244g_settings_action_change_state (GAction *action,
3245 GVariant *value)
3246{
3247 GSettingsAction *gsa = (GSettingsAction *) action;
3248
3249 if (g_settings_schema_key_type_check (key: &gsa->key, value) && g_settings_schema_key_range_check (key: &gsa->key, value))
3250 g_settings_write_to_backend (settings: gsa->settings, key: &gsa->key, value);
3251}
3252
3253static void
3254g_settings_action_activate (GAction *action,
3255 GVariant *parameter)
3256{
3257 GSettingsAction *gsa = (GSettingsAction *) action;
3258
3259 if (g_variant_is_of_type (value: gsa->key.default_value, G_VARIANT_TYPE_BOOLEAN))
3260 {
3261 GVariant *old;
3262
3263 if (parameter != NULL)
3264 return;
3265
3266 old = g_settings_action_get_state (action);
3267 parameter = g_variant_new_boolean (value: !g_variant_get_boolean (value: old));
3268 g_variant_unref (value: old);
3269 }
3270
3271 g_action_change_state (action, value: parameter);
3272}
3273
3274static void
3275g_settings_action_get_property (GObject *object, guint prop_id,
3276 GValue *value, GParamSpec *pspec)
3277{
3278 GAction *action = G_ACTION (object);
3279
3280 switch (prop_id)
3281 {
3282 case ACTION_PROP_NAME:
3283 g_value_set_string (value, v_string: g_settings_action_get_name (action));
3284 break;
3285
3286 case ACTION_PROP_PARAMETER_TYPE:
3287 g_value_set_boxed (value, v_boxed: g_settings_action_get_parameter_type (action));
3288 break;
3289
3290 case ACTION_PROP_ENABLED:
3291 g_value_set_boolean (value, v_boolean: g_settings_action_get_enabled (action));
3292 break;
3293
3294 case ACTION_PROP_STATE_TYPE:
3295 g_value_set_boxed (value, v_boxed: g_settings_action_get_state_type (action));
3296 break;
3297
3298 case ACTION_PROP_STATE:
3299 g_value_take_variant (value, variant: g_settings_action_get_state (action));
3300 break;
3301
3302 default:
3303 g_assert_not_reached ();
3304 }
3305}
3306
3307static void
3308g_settings_action_finalize (GObject *object)
3309{
3310 GSettingsAction *gsa = (GSettingsAction *) object;
3311
3312 g_signal_handlers_disconnect_by_data (gsa->settings, gsa);
3313 g_object_unref (object: gsa->settings);
3314 g_settings_schema_key_clear (key: &gsa->key);
3315
3316 G_OBJECT_CLASS (g_settings_action_parent_class)
3317 ->finalize (object);
3318}
3319
3320static void
3321g_settings_action_init (GSettingsAction *gsa)
3322{
3323}
3324
3325static void
3326g_settings_action_iface_init (GActionInterface *iface)
3327{
3328 iface->get_name = g_settings_action_get_name;
3329 iface->get_parameter_type = g_settings_action_get_parameter_type;
3330 iface->get_enabled = g_settings_action_get_enabled;
3331 iface->get_state_type = g_settings_action_get_state_type;
3332 iface->get_state = g_settings_action_get_state;
3333 iface->get_state_hint = g_settings_action_get_state_hint;
3334 iface->change_state = g_settings_action_change_state;
3335 iface->activate = g_settings_action_activate;
3336}
3337
3338static void
3339g_settings_action_class_init (GSettingsActionClass *class)
3340{
3341 class->get_property = g_settings_action_get_property;
3342 class->finalize = g_settings_action_finalize;
3343
3344 g_object_class_override_property (oclass: class, property_id: ACTION_PROP_NAME, name: "name");
3345 g_object_class_override_property (oclass: class, property_id: ACTION_PROP_PARAMETER_TYPE, name: "parameter-type");
3346 g_object_class_override_property (oclass: class, property_id: ACTION_PROP_ENABLED, name: "enabled");
3347 g_object_class_override_property (oclass: class, property_id: ACTION_PROP_STATE_TYPE, name: "state-type");
3348 g_object_class_override_property (oclass: class, property_id: ACTION_PROP_STATE, name: "state");
3349}
3350
3351static void
3352g_settings_action_changed (GSettings *settings,
3353 const gchar *key,
3354 gpointer user_data)
3355{
3356 g_object_notify (object: user_data, property_name: "state");
3357}
3358
3359static void
3360g_settings_action_enabled_changed (GSettings *settings,
3361 const gchar *key,
3362 gpointer user_data)
3363{
3364 g_object_notify (object: user_data, property_name: "enabled");
3365}
3366
3367/**
3368 * g_settings_create_action:
3369 * @settings: a #GSettings
3370 * @key: the name of a key in @settings
3371 *
3372 * Creates a #GAction corresponding to a given #GSettings key.
3373 *
3374 * The action has the same name as the key.
3375 *
3376 * The value of the key becomes the state of the action and the action
3377 * is enabled when the key is writable. Changing the state of the
3378 * action results in the key being written to. Changes to the value or
3379 * writability of the key cause appropriate change notifications to be
3380 * emitted for the action.
3381 *
3382 * For boolean-valued keys, action activations take no parameter and
3383 * result in the toggling of the value. For all other types,
3384 * activations take the new value for the key (which must have the
3385 * correct type).
3386 *
3387 * Returns: (transfer full): a new #GAction
3388 *
3389 * Since: 2.32
3390 **/
3391GAction *
3392g_settings_create_action (GSettings *settings,
3393 const gchar *key)
3394{
3395 GSettingsAction *gsa;
3396 gchar *detailed_signal;
3397
3398 g_return_val_if_fail (G_IS_SETTINGS (settings), NULL);
3399 g_return_val_if_fail (key != NULL, NULL);
3400
3401 gsa = g_object_new (object_type: g_settings_action_get_type (), NULL);
3402 gsa->settings = g_object_ref (settings);
3403 g_settings_schema_key_init (key: &gsa->key, schema: settings->priv->schema, name: key);
3404
3405 detailed_signal = g_strdup_printf (format: "changed::%s", key);
3406 g_signal_connect (settings, detailed_signal, G_CALLBACK (g_settings_action_changed), gsa);
3407 g_free (mem: detailed_signal);
3408 detailed_signal = g_strdup_printf (format: "writable-changed::%s", key);
3409 g_signal_connect (settings, detailed_signal, G_CALLBACK (g_settings_action_enabled_changed), gsa);
3410 g_free (mem: detailed_signal);
3411
3412 return G_ACTION (gsa);
3413}
3414
3415/* Epilogue {{{1 */
3416
3417/* vim:set foldmethod=marker: */
3418

source code of gtk/subprojects/glib/gio/gsettings.c