Coverage Report

Created: 2025-08-26 06:51

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