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