1 /* 2 * This file is part of gtkD. 3 * 4 * gtkD is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License 6 * as published by the Free Software Foundation; either version 3 7 * of the License, or (at your option) any later version, with 8 * some exceptions, please read the COPYING file. 9 * 10 * gtkD is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with gtkD; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA 18 */ 19 20 // generated automatically - do not change 21 // find conversion definition on APILookup.txt 22 // implement new conversion functionalities on the wrap.utils pakage 23 24 25 module gio.Settings; 26 27 private import gio.Action; 28 private import gio.ActionIF; 29 private import gio.SettingsSchema; 30 private import glib.ConstructionException; 31 private import glib.Str; 32 private import glib.Variant; 33 private import gobject.ObjectG; 34 private import gobject.Signals; 35 public import gtkc.gdktypes; 36 private import gtkc.gio; 37 public import gtkc.giotypes; 38 39 40 /** 41 * The #GSettings class provides a convenient API for storing and retrieving 42 * application settings. 43 * 44 * Reads and writes can be considered to be non-blocking. Reading 45 * settings with #GSettings is typically extremely fast: on 46 * approximately the same order of magnitude (but slower than) a 47 * #GHashTable lookup. Writing settings is also extremely fast in terms 48 * of time to return to your application, but can be extremely expensive 49 * for other threads and other processes. Many settings backends 50 * (including dconf) have lazy initialisation which means in the common 51 * case of the user using their computer without modifying any settings 52 * a lot of work can be avoided. For dconf, the D-Bus service doesn't 53 * even need to be started in this case. For this reason, you should 54 * only ever modify #GSettings keys in response to explicit user action. 55 * Particular care should be paid to ensure that modifications are not 56 * made during startup -- for example, when setting the initial value 57 * of preferences widgets. The built-in g_settings_bind() functionality 58 * is careful not to write settings in response to notify signals as a 59 * result of modifications that it makes to widgets. 60 * 61 * When creating a GSettings instance, you have to specify a schema 62 * that describes the keys in your settings and their types and default 63 * values, as well as some other information. 64 * 65 * Normally, a schema has as fixed path that determines where the settings 66 * are stored in the conceptual global tree of settings. However, schemas 67 * can also be 'relocatable', i.e. not equipped with a fixed path. This is 68 * useful e.g. when the schema describes an 'account', and you want to be 69 * able to store a arbitrary number of accounts. 70 * 71 * Paths must start with and end with a forward slash character ('/') 72 * and must not contain two sequential slash characters. Paths should 73 * be chosen based on a domain name associated with the program or 74 * library to which the settings belong. Examples of paths are 75 * "/org/gtk/settings/file-chooser/" and "/ca/desrt/dconf-editor/". 76 * Paths should not start with "/apps/", "/desktop/" or "/system/" as 77 * they often did in GConf. 78 * 79 * Unlike other configuration systems (like GConf), GSettings does not 80 * restrict keys to basic types like strings and numbers. GSettings stores 81 * values as #GVariant, and allows any #GVariantType for keys. Key names 82 * are restricted to lowercase characters, numbers and '-'. Furthermore, 83 * the names must begin with a lowercase character, must not end 84 * with a '-', and must not contain consecutive dashes. 85 * 86 * Similar to GConf, the default values in GSettings schemas can be 87 * localized, but the localized values are stored in gettext catalogs 88 * and looked up with the domain that is specified in the 89 * gettext-domain attribute of the <schemalist> or <schema> 90 * elements and the category that is specified in the l10n attribute of 91 * the <key> element. 92 * 93 * GSettings uses schemas in a compact binary form that is created 94 * by the [glib-compile-schemas][glib-compile-schemas] 95 * utility. The input is a schema description in an XML format. 96 * 97 * A DTD for the gschema XML format can be found here: 98 * [gschema.dtd](https://git.gnome.org/browse/glib/tree/gio/gschema.dtd) 99 * 100 * The [glib-compile-schemas][glib-compile-schemas] tool expects schema 101 * files to have the extension `.gschema.xml`. 102 * 103 * At runtime, schemas are identified by their id (as specified in the 104 * id attribute of the <schema> element). The convention for schema 105 * ids is to use a dotted name, similar in style to a D-Bus bus name, 106 * e.g. "org.gnome.SessionManager". In particular, if the settings are 107 * for a specific service that owns a D-Bus bus name, the D-Bus bus name 108 * and schema id should match. For schemas which deal with settings not 109 * associated with one named application, the id should not use 110 * StudlyCaps, e.g. "org.gnome.font-rendering". 111 * 112 * In addition to #GVariant types, keys can have types that have 113 * enumerated types. These can be described by a <choice>, 114 * <enum> or <flags> element, as seen in the 115 * [example][schema-enumerated]. The underlying type of such a key 116 * is string, but you can use g_settings_get_enum(), g_settings_set_enum(), 117 * g_settings_get_flags(), g_settings_set_flags() access the numeric values 118 * corresponding to the string value of enum and flags keys. 119 * 120 * An example for default value: 121 * |[ 122 * <schemalist> 123 * <schema id="org.gtk.Test" path="/org/gtk/Test/" gettext-domain="test"> 124 * 125 * <key name="greeting" type="s"> 126 * <default l10n="messages">"Hello, earthlings"</default> 127 * <summary>A greeting</summary> 128 * <description> 129 * Greeting of the invading martians 130 * </description> 131 * </key> 132 * 133 * <key name="box" type="(ii)"> 134 * <default>(20,30)</default> 135 * </key> 136 * 137 * </schema> 138 * </schemalist> 139 * ]| 140 * 141 * An example for ranges, choices and enumerated types: 142 * |[ 143 * <schemalist> 144 * 145 * <enum id="org.gtk.Test.myenum"> 146 * <value nick="first" value="1"/> 147 * <value nick="second" value="2"/> 148 * </enum> 149 * 150 * <flags id="org.gtk.Test.myflags"> 151 * <value nick="flag1" value="1"/> 152 * <value nick="flag2" value="2"/> 153 * <value nick="flag3" value="4"/> 154 * </flags> 155 * 156 * <schema id="org.gtk.Test"> 157 * 158 * <key name="key-with-range" type="i"> 159 * <range min="1" max="100"/> 160 * <default>10</default> 161 * </key> 162 * 163 * <key name="key-with-choices" type="s"> 164 * <choices> 165 * <choice value='Elisabeth'/> 166 * <choice value='Annabeth'/> 167 * <choice value='Joe'/> 168 * </choices> 169 * <aliases> 170 * <alias value='Anna' target='Annabeth'/> 171 * <alias value='Beth' target='Elisabeth'/> 172 * </aliases> 173 * <default>'Joe'</default> 174 * </key> 175 * 176 * <key name='enumerated-key' enum='org.gtk.Test.myenum'> 177 * <default>'first'</default> 178 * </key> 179 * 180 * <key name='flags-key' flags='org.gtk.Test.myflags'> 181 * <default>["flag1",flag2"]</default> 182 * </key> 183 * </schema> 184 * </schemalist> 185 * ]| 186 * 187 * ## Vendor overrides 188 * 189 * Default values are defined in the schemas that get installed by 190 * an application. Sometimes, it is necessary for a vendor or distributor 191 * to adjust these defaults. Since patching the XML source for the schema 192 * is inconvenient and error-prone, 193 * [glib-compile-schemas][glib-compile-schemas] reads so-called vendor 194 * override' files. These are keyfiles in the same directory as the XML 195 * schema sources which can override default values. The schema id serves 196 * as the group name in the key file, and the values are expected in 197 * serialized GVariant form, as in the following example: 198 * |[ 199 * [org.gtk.Example] 200 * key1='string' 201 * key2=1.5 202 * ]| 203 * 204 * glib-compile-schemas expects schema files to have the extension 205 * `.gschema.override`. 206 * 207 * ## Binding 208 * 209 * A very convenient feature of GSettings lets you bind #GObject properties 210 * directly to settings, using g_settings_bind(). Once a GObject property 211 * has been bound to a setting, changes on either side are automatically 212 * propagated to the other side. GSettings handles details like mapping 213 * between GObject and GVariant types, and preventing infinite cycles. 214 * 215 * This makes it very easy to hook up a preferences dialog to the 216 * underlying settings. To make this even more convenient, GSettings 217 * looks for a boolean property with the name "sensitivity" and 218 * automatically binds it to the writability of the bound setting. 219 * If this 'magic' gets in the way, it can be suppressed with the 220 * #G_SETTINGS_BIND_NO_SENSITIVITY flag. 221 */ 222 public class Settings : ObjectG 223 { 224 /** the main Gtk struct */ 225 protected GSettings* gSettings; 226 227 /** Get the main Gtk struct */ 228 public GSettings* getSettingsStruct() 229 { 230 return gSettings; 231 } 232 233 /** the main Gtk struct as a void* */ 234 protected override void* getStruct() 235 { 236 return cast(void*)gSettings; 237 } 238 239 protected override void setStruct(GObject* obj) 240 { 241 gSettings = cast(GSettings*)obj; 242 super.setStruct(obj); 243 } 244 245 /** 246 * Sets our main struct and passes it to the parent class. 247 */ 248 public this (GSettings* gSettings, bool ownedRef = false) 249 { 250 this.gSettings = gSettings; 251 super(cast(GObject*)gSettings, ownedRef); 252 } 253 254 /** 255 */ 256 257 public static GType getType() 258 { 259 return g_settings_get_type(); 260 } 261 262 /** 263 * Creates a new #GSettings object with the schema specified by 264 * @schema_id. 265 * 266 * Signals on the newly created #GSettings object will be dispatched 267 * via the thread-default #GMainContext in effect at the time of the 268 * call to g_settings_new(). The new #GSettings will hold a reference 269 * on the context. See g_main_context_push_thread_default(). 270 * 271 * Params: 272 * schemaId = the id of the schema 273 * 274 * Return: a new #GSettings object 275 * 276 * Since: 2.26 277 * 278 * Throws: ConstructionException GTK+ fails to create the object. 279 */ 280 public this(string schemaId) 281 { 282 auto p = g_settings_new(Str.toStringz(schemaId)); 283 284 if(p is null) 285 { 286 throw new ConstructionException("null returned by new"); 287 } 288 289 this(cast(GSettings*) p, true); 290 } 291 292 /** 293 * Creates a new #GSettings object with a given schema, backend and 294 * path. 295 * 296 * It should be extremely rare that you ever want to use this function. 297 * It is made available for advanced use-cases (such as plugin systems 298 * that want to provide access to schemas loaded from custom locations, 299 * etc). 300 * 301 * At the most basic level, a #GSettings object is a pure composition of 302 * 4 things: a #GSettingsSchema, a #GSettingsBackend, a path within that 303 * backend, and a #GMainContext to which signals are dispatched. 304 * 305 * This constructor therefore gives you full control over constructing 306 * #GSettings instances. The first 4 parameters are given directly as 307 * @schema, @backend and @path, and the main context is taken from the 308 * thread-default (as per g_settings_new()). 309 * 310 * If @backend is %NULL then the default backend is used. 311 * 312 * If @path is %NULL then the path from the schema is used. It is an 313 * error f @path is %NULL and the schema has no path of its own or if 314 * @path is non-%NULL and not equal to the path that the schema does 315 * have. 316 * 317 * Params: 318 * schema = a #GSettingsSchema 319 * backend = a #GSettingsBackend 320 * path = the path to use 321 * 322 * Return: a new #GSettings object 323 * 324 * Since: 2.32 325 * 326 * Throws: ConstructionException GTK+ fails to create the object. 327 */ 328 public this(SettingsSchema schema, GSettingsBackend* backend, string path) 329 { 330 auto p = g_settings_new_full((schema is null) ? null : schema.getSettingsSchemaStruct(), backend, Str.toStringz(path)); 331 332 if(p is null) 333 { 334 throw new ConstructionException("null returned by new_full"); 335 } 336 337 this(cast(GSettings*) p, true); 338 } 339 340 /** 341 * Creates a new #GSettings object with the schema specified by 342 * @schema_id and a given #GSettingsBackend. 343 * 344 * Creating a #GSettings object with a different backend allows accessing 345 * settings from a database other than the usual one. For example, it may make 346 * sense to pass a backend corresponding to the "defaults" settings database on 347 * the system to get a settings object that modifies the system default 348 * settings instead of the settings for this user. 349 * 350 * Params: 351 * schemaId = the id of the schema 352 * backend = the #GSettingsBackend to use 353 * 354 * Return: a new #GSettings object 355 * 356 * Since: 2.26 357 * 358 * Throws: ConstructionException GTK+ fails to create the object. 359 */ 360 public this(string schemaId, GSettingsBackend* backend) 361 { 362 auto p = g_settings_new_with_backend(Str.toStringz(schemaId), backend); 363 364 if(p is null) 365 { 366 throw new ConstructionException("null returned by new_with_backend"); 367 } 368 369 this(cast(GSettings*) p, true); 370 } 371 372 /** 373 * Creates a new #GSettings object with the schema specified by 374 * @schema_id and a given #GSettingsBackend and path. 375 * 376 * This is a mix of g_settings_new_with_backend() and 377 * g_settings_new_with_path(). 378 * 379 * Params: 380 * schemaId = the id of the schema 381 * backend = the #GSettingsBackend to use 382 * path = the path to use 383 * 384 * Return: a new #GSettings object 385 * 386 * Since: 2.26 387 * 388 * Throws: ConstructionException GTK+ fails to create the object. 389 */ 390 public this(string schemaId, GSettingsBackend* backend, string path) 391 { 392 auto p = g_settings_new_with_backend_and_path(Str.toStringz(schemaId), backend, Str.toStringz(path)); 393 394 if(p is null) 395 { 396 throw new ConstructionException("null returned by new_with_backend_and_path"); 397 } 398 399 this(cast(GSettings*) p, true); 400 } 401 402 /** 403 * Creates a new #GSettings object with the relocatable schema specified 404 * by @schema_id and a given path. 405 * 406 * You only need to do this if you want to directly create a settings 407 * object with a schema that doesn't have a specified path of its own. 408 * That's quite rare. 409 * 410 * It is a programmer error to call this function for a schema that 411 * has an explicitly specified path. 412 * 413 * It is a programmer error if @path is not a valid path. A valid path 414 * begins and ends with '/' and does not contain two consecutive '/' 415 * characters. 416 * 417 * Params: 418 * schemaId = the id of the schema 419 * path = the path to use 420 * 421 * Return: a new #GSettings object 422 * 423 * Since: 2.26 424 * 425 * Throws: ConstructionException GTK+ fails to create the object. 426 */ 427 public this(string schemaId, string path) 428 { 429 auto p = g_settings_new_with_path(Str.toStringz(schemaId), Str.toStringz(path)); 430 431 if(p is null) 432 { 433 throw new ConstructionException("null returned by new_with_path"); 434 } 435 436 this(cast(GSettings*) p, true); 437 } 438 439 /** 440 * 441 * 442 * Deprecated: Use g_settings_schema_source_list_schemas() instead 443 * 444 * Return: a list of relocatable 445 * #GSettings schemas that are available. The list must not be 446 * modified or freed. 447 * 448 * Since: 2.28 449 */ 450 public static string[] listRelocatableSchemas() 451 { 452 return Str.toStringArray(g_settings_list_relocatable_schemas()); 453 } 454 455 /** 456 * 457 * 458 * Deprecated: Use g_settings_schema_source_list_schemas() instead. 459 * If you used g_settings_list_schemas() to check for the presence of 460 * a particular schema, use g_settings_schema_source_lookup() instead 461 * of your whole loop. 462 * 463 * Return: a list of #GSettings 464 * schemas that are available. The list must not be modified or 465 * freed. 466 * 467 * Since: 2.26 468 */ 469 public static string[] listSchemas() 470 { 471 return Str.toStringArray(g_settings_list_schemas()); 472 } 473 474 /** 475 * Ensures that all pending operations for the given are complete for 476 * the default backend. 477 * 478 * Writes made to a #GSettings are handled asynchronously. For this 479 * reason, it is very unlikely that the changes have it to disk by the 480 * time g_settings_set() returns. 481 * 482 * This call will block until all of the writes have made it to the 483 * backend. Since the mainloop is not running, no change notifications 484 * will be dispatched during this call (but some may be queued by the 485 * time the call is done). 486 */ 487 public static void sync() 488 { 489 g_settings_sync(); 490 } 491 492 /** 493 * Removes an existing binding for @property on @object. 494 * 495 * Note that bindings are automatically removed when the 496 * object is finalized, so it is rarely necessary to call this 497 * function. 498 * 499 * Params: 500 * object = the object 501 * property = the property whose binding is removed 502 * 503 * Since: 2.26 504 */ 505 public static void unbind(void* object, string property) 506 { 507 g_settings_unbind(object, Str.toStringz(property)); 508 } 509 510 /** 511 * Applies any changes that have been made to the settings. This 512 * function does nothing unless @settings is in 'delay-apply' mode; 513 * see g_settings_delay(). In the normal case settings are always 514 * applied immediately. 515 */ 516 public void apply() 517 { 518 g_settings_apply(gSettings); 519 } 520 521 /** 522 * Create a binding between the @key in the @settings object 523 * and the property @property of @object. 524 * 525 * The binding uses the default GIO mapping functions to map 526 * between the settings and property values. These functions 527 * handle booleans, numeric types and string types in a 528 * straightforward way. Use g_settings_bind_with_mapping() if 529 * you need a custom mapping, or map between types that are not 530 * supported by the default mapping functions. 531 * 532 * Unless the @flags include %G_SETTINGS_BIND_NO_SENSITIVITY, this 533 * function also establishes a binding between the writability of 534 * @key and the "sensitive" property of @object (if @object has 535 * a boolean property by that name). See g_settings_bind_writable() 536 * for more details about writable bindings. 537 * 538 * Note that the lifecycle of the binding is tied to the object, 539 * and that you can have only one binding per object property. 540 * If you bind the same property twice on the same object, the second 541 * binding overrides the first one. 542 * 543 * Params: 544 * key = the key to bind 545 * object = a #GObject 546 * property = the name of the property to bind 547 * flags = flags for the binding 548 * 549 * Since: 2.26 550 */ 551 public void bind(string key, ObjectG object, string property, GSettingsBindFlags flags) 552 { 553 g_settings_bind(gSettings, Str.toStringz(key), (object is null) ? null : object.getObjectGStruct(), Str.toStringz(property), flags); 554 } 555 556 /** 557 * Create a binding between the @key in the @settings object 558 * and the property @property of @object. 559 * 560 * The binding uses the provided mapping functions to map between 561 * settings and property values. 562 * 563 * Note that the lifecycle of the binding is tied to the object, 564 * and that you can have only one binding per object property. 565 * If you bind the same property twice on the same object, the second 566 * binding overrides the first one. 567 * 568 * Params: 569 * key = the key to bind 570 * object = a #GObject 571 * property = the name of the property to bind 572 * flags = flags for the binding 573 * getMapping = a function that gets called to convert values 574 * from @settings to @object, or %NULL to use the default GIO mapping 575 * setMapping = a function that gets called to convert values 576 * from @object to @settings, or %NULL to use the default GIO mapping 577 * userData = data that gets passed to @get_mapping and @set_mapping 578 * destroy = #GDestroyNotify function for @user_data 579 * 580 * Since: 2.26 581 */ 582 public void bindWithMapping(string key, ObjectG object, string property, GSettingsBindFlags flags, GSettingsBindGetMapping getMapping, GSettingsBindSetMapping setMapping, void* userData, GDestroyNotify destroy) 583 { 584 g_settings_bind_with_mapping(gSettings, Str.toStringz(key), (object is null) ? null : object.getObjectGStruct(), Str.toStringz(property), flags, getMapping, setMapping, userData, destroy); 585 } 586 587 /** 588 * Create a binding between the writability of @key in the 589 * @settings object and the property @property of @object. 590 * The property must be boolean; "sensitive" or "visible" 591 * properties of widgets are the most likely candidates. 592 * 593 * Writable bindings are always uni-directional; changes of the 594 * writability of the setting will be propagated to the object 595 * property, not the other way. 596 * 597 * When the @inverted argument is %TRUE, the binding inverts the 598 * value as it passes from the setting to the object, i.e. @property 599 * will be set to %TRUE if the key is not writable. 600 * 601 * Note that the lifecycle of the binding is tied to the object, 602 * and that you can have only one binding per object property. 603 * If you bind the same property twice on the same object, the second 604 * binding overrides the first one. 605 * 606 * Params: 607 * key = the key to bind 608 * object = a #GObject 609 * property = the name of a boolean property to bind 610 * inverted = whether to 'invert' the value 611 * 612 * Since: 2.26 613 */ 614 public void bindWritable(string key, ObjectG object, string property, bool inverted) 615 { 616 g_settings_bind_writable(gSettings, Str.toStringz(key), (object is null) ? null : object.getObjectGStruct(), Str.toStringz(property), inverted); 617 } 618 619 /** 620 * Creates a #GAction corresponding to a given #GSettings key. 621 * 622 * The action has the same name as the key. 623 * 624 * The value of the key becomes the state of the action and the action 625 * is enabled when the key is writable. Changing the state of the 626 * action results in the key being written to. Changes to the value or 627 * writability of the key cause appropriate change notifications to be 628 * emitted for the action. 629 * 630 * For boolean-valued keys, action activations take no parameter and 631 * result in the toggling of the value. For all other types, 632 * activations take the new value for the key (which must have the 633 * correct type). 634 * 635 * Params: 636 * key = the name of a key in @settings 637 * 638 * Return: a new #GAction 639 * 640 * Since: 2.32 641 */ 642 public ActionIF createAction(string key) 643 { 644 auto p = g_settings_create_action(gSettings, Str.toStringz(key)); 645 646 if(p is null) 647 { 648 return null; 649 } 650 651 return ObjectG.getDObject!(Action, ActionIF)(cast(GAction*) p); 652 } 653 654 /** 655 * Changes the #GSettings object into 'delay-apply' mode. In this 656 * mode, changes to @settings are not immediately propagated to the 657 * backend, but kept locally until g_settings_apply() is called. 658 * 659 * Since: 2.26 660 */ 661 public void delay() 662 { 663 g_settings_delay(gSettings); 664 } 665 666 /** 667 * Gets the value that is stored at @key in @settings. 668 * 669 * A convenience variant of g_settings_get() for booleans. 670 * 671 * It is a programmer error to give a @key that isn't specified as 672 * having a boolean type in the schema for @settings. 673 * 674 * Params: 675 * key = the key to get the value for 676 * 677 * Return: a boolean 678 * 679 * Since: 2.26 680 */ 681 public bool getBoolean(string key) 682 { 683 return g_settings_get_boolean(gSettings, Str.toStringz(key)) != 0; 684 } 685 686 /** 687 * Creates a child settings object which has a base path of 688 * `base-path/@name`, where `base-path` is the base path of 689 * @settings. 690 * 691 * The schema for the child settings object must have been declared 692 * in the schema of @settings using a <child> element. 693 * 694 * Params: 695 * name = the name of the child schema 696 * 697 * Return: a 'child' settings object 698 * 699 * Since: 2.26 700 */ 701 public Settings getChild(string name) 702 { 703 auto p = g_settings_get_child(gSettings, Str.toStringz(name)); 704 705 if(p is null) 706 { 707 return null; 708 } 709 710 return ObjectG.getDObject!(Settings)(cast(GSettings*) p, true); 711 } 712 713 /** 714 * Gets the "default value" of a key. 715 * 716 * This is the value that would be read if g_settings_reset() were to be 717 * called on the key. 718 * 719 * Note that this may be a different value than returned by 720 * g_settings_schema_key_get_default_value() if the system administrator 721 * has provided a default value. 722 * 723 * Comparing the return values of g_settings_get_default_value() and 724 * g_settings_get_value() is not sufficient for determining if a value 725 * has been set because the user may have explicitly set the value to 726 * something that happens to be equal to the default. The difference 727 * here is that if the default changes in the future, the user's key 728 * will still be set. 729 * 730 * This function may be useful for adding an indication to a UI of what 731 * the default value was before the user set it. 732 * 733 * It is a programmer error to give a @key that isn't contained in the 734 * schema for @settings. 735 * 736 * Params: 737 * key = the key to get the default value for 738 * 739 * Return: the default value 740 * 741 * Since: 2.40 742 */ 743 public Variant getDefaultValue(string key) 744 { 745 auto p = g_settings_get_default_value(gSettings, Str.toStringz(key)); 746 747 if(p is null) 748 { 749 return null; 750 } 751 752 return new Variant(cast(GVariant*) p); 753 } 754 755 /** 756 * Gets the value that is stored at @key in @settings. 757 * 758 * A convenience variant of g_settings_get() for doubles. 759 * 760 * It is a programmer error to give a @key that isn't specified as 761 * having a 'double' type in the schema for @settings. 762 * 763 * Params: 764 * key = the key to get the value for 765 * 766 * Return: a double 767 * 768 * Since: 2.26 769 */ 770 public double getDouble(string key) 771 { 772 return g_settings_get_double(gSettings, Str.toStringz(key)); 773 } 774 775 /** 776 * Gets the value that is stored in @settings for @key and converts it 777 * to the enum value that it represents. 778 * 779 * In order to use this function the type of the value must be a string 780 * and it must be marked in the schema file as an enumerated type. 781 * 782 * It is a programmer error to give a @key that isn't contained in the 783 * schema for @settings or is not marked as an enumerated type. 784 * 785 * If the value stored in the configuration database is not a valid 786 * value for the enumerated type then this function will return the 787 * default value. 788 * 789 * Params: 790 * key = the key to get the value for 791 * 792 * Return: the enum value 793 * 794 * Since: 2.26 795 */ 796 public int getEnum(string key) 797 { 798 return g_settings_get_enum(gSettings, Str.toStringz(key)); 799 } 800 801 /** 802 * Gets the value that is stored in @settings for @key and converts it 803 * to the flags value that it represents. 804 * 805 * In order to use this function the type of the value must be an array 806 * of strings and it must be marked in the schema file as an flags type. 807 * 808 * It is a programmer error to give a @key that isn't contained in the 809 * schema for @settings or is not marked as a flags type. 810 * 811 * If the value stored in the configuration database is not a valid 812 * value for the flags type then this function will return the default 813 * value. 814 * 815 * Params: 816 * key = the key to get the value for 817 * 818 * Return: the flags value 819 * 820 * Since: 2.26 821 */ 822 public uint getFlags(string key) 823 { 824 return g_settings_get_flags(gSettings, Str.toStringz(key)); 825 } 826 827 /** 828 * Returns whether the #GSettings object has any unapplied 829 * changes. This can only be the case if it is in 'delayed-apply' mode. 830 * 831 * Return: %TRUE if @settings has unapplied changes 832 * 833 * Since: 2.26 834 */ 835 public bool getHasUnapplied() 836 { 837 return g_settings_get_has_unapplied(gSettings) != 0; 838 } 839 840 /** 841 * Gets the value that is stored at @key in @settings. 842 * 843 * A convenience variant of g_settings_get() for 32-bit integers. 844 * 845 * It is a programmer error to give a @key that isn't specified as 846 * having a int32 type in the schema for @settings. 847 * 848 * Params: 849 * key = the key to get the value for 850 * 851 * Return: an integer 852 * 853 * Since: 2.26 854 */ 855 public int getInt(string key) 856 { 857 return g_settings_get_int(gSettings, Str.toStringz(key)); 858 } 859 860 /** 861 * Gets the value that is stored at @key in @settings, subject to 862 * application-level validation/mapping. 863 * 864 * You should use this function when the application needs to perform 865 * some processing on the value of the key (for example, parsing). The 866 * @mapping function performs that processing. If the function 867 * indicates that the processing was unsuccessful (due to a parse error, 868 * for example) then the mapping is tried again with another value. 869 * 870 * This allows a robust 'fall back to defaults' behaviour to be 871 * implemented somewhat automatically. 872 * 873 * The first value that is tried is the user's setting for the key. If 874 * the mapping function fails to map this value, other values may be 875 * tried in an unspecified order (system or site defaults, translated 876 * schema default values, untranslated schema default values, etc). 877 * 878 * If the mapping function fails for all possible values, one additional 879 * attempt is made: the mapping function is called with a %NULL value. 880 * If the mapping function still indicates failure at this point then 881 * the application will be aborted. 882 * 883 * The result parameter for the @mapping function is pointed to a 884 * #gpointer which is initially set to %NULL. The same pointer is given 885 * to each invocation of @mapping. The final value of that #gpointer is 886 * what is returned by this function. %NULL is valid; it is returned 887 * just as any other value would be. 888 * 889 * Params: 890 * key = the key to get the value for 891 * mapping = the function to map the value in the 892 * settings database to the value used by the application 893 * userData = user data for @mapping 894 * 895 * Return: the result, which may be %NULL 896 */ 897 public void* getMapped(string key, GSettingsGetMapping mapping, void* userData) 898 { 899 return g_settings_get_mapped(gSettings, Str.toStringz(key), mapping, userData); 900 } 901 902 /** 903 * Queries the range of a key. 904 * 905 * Deprecated: Use g_settings_schema_key_get_range() instead. 906 * 907 * Params: 908 * key = the key to query the range of 909 * 910 * Since: 2.28 911 */ 912 public Variant getRange(string key) 913 { 914 auto p = g_settings_get_range(gSettings, Str.toStringz(key)); 915 916 if(p is null) 917 { 918 return null; 919 } 920 921 return new Variant(cast(GVariant*) p); 922 } 923 924 /** 925 * Gets the value that is stored at @key in @settings. 926 * 927 * A convenience variant of g_settings_get() for strings. 928 * 929 * It is a programmer error to give a @key that isn't specified as 930 * having a string type in the schema for @settings. 931 * 932 * Params: 933 * key = the key to get the value for 934 * 935 * Return: a newly-allocated string 936 * 937 * Since: 2.26 938 */ 939 public string getString(string key) 940 { 941 return Str.toString(g_settings_get_string(gSettings, Str.toStringz(key))); 942 } 943 944 /** 945 * A convenience variant of g_settings_get() for string arrays. 946 * 947 * It is a programmer error to give a @key that isn't specified as 948 * having an array of strings type in the schema for @settings. 949 * 950 * Params: 951 * key = the key to get the value for 952 * 953 * Return: a 954 * newly-allocated, %NULL-terminated array of strings, the value that 955 * is stored at @key in @settings. 956 * 957 * Since: 2.26 958 */ 959 public string[] getStrv(string key) 960 { 961 return Str.toStringArray(g_settings_get_strv(gSettings, Str.toStringz(key))); 962 } 963 964 /** 965 * Gets the value that is stored at @key in @settings. 966 * 967 * A convenience variant of g_settings_get() for 32-bit unsigned 968 * integers. 969 * 970 * It is a programmer error to give a @key that isn't specified as 971 * having a uint32 type in the schema for @settings. 972 * 973 * Params: 974 * key = the key to get the value for 975 * 976 * Return: an unsigned integer 977 * 978 * Since: 2.30 979 */ 980 public uint getUint(string key) 981 { 982 return g_settings_get_uint(gSettings, Str.toStringz(key)); 983 } 984 985 /** 986 * Checks the "user value" of a key, if there is one. 987 * 988 * The user value of a key is the last value that was set by the user. 989 * 990 * After calling g_settings_reset() this function should always return 991 * %NULL (assuming something is not wrong with the system 992 * configuration). 993 * 994 * It is possible that g_settings_get_value() will return a different 995 * value than this function. This can happen in the case that the user 996 * set a value for a key that was subsequently locked down by the system 997 * administrator -- this function will return the user's old value. 998 * 999 * This function may be useful for adding a "reset" option to a UI or 1000 * for providing indication that a particular value has been changed. 1001 * 1002 * It is a programmer error to give a @key that isn't contained in the 1003 * schema for @settings. 1004 * 1005 * Params: 1006 * key = the key to get the user value for 1007 * 1008 * Return: the user's value, if set 1009 * 1010 * Since: 2.40 1011 */ 1012 public Variant getUserValue(string key) 1013 { 1014 auto p = g_settings_get_user_value(gSettings, Str.toStringz(key)); 1015 1016 if(p is null) 1017 { 1018 return null; 1019 } 1020 1021 return new Variant(cast(GVariant*) p); 1022 } 1023 1024 /** 1025 * Gets the value that is stored in @settings for @key. 1026 * 1027 * It is a programmer error to give a @key that isn't contained in the 1028 * schema for @settings. 1029 * 1030 * Params: 1031 * key = the key to get the value for 1032 * 1033 * Return: a new #GVariant 1034 * 1035 * Since: 2.26 1036 */ 1037 public Variant getValue(string key) 1038 { 1039 auto p = g_settings_get_value(gSettings, Str.toStringz(key)); 1040 1041 if(p is null) 1042 { 1043 return null; 1044 } 1045 1046 return new Variant(cast(GVariant*) p); 1047 } 1048 1049 /** 1050 * Finds out if a key can be written or not 1051 * 1052 * Params: 1053 * name = the name of a key 1054 * 1055 * Return: %TRUE if the key @name is writable 1056 * 1057 * Since: 2.26 1058 */ 1059 public bool isWritable(string name) 1060 { 1061 return g_settings_is_writable(gSettings, Str.toStringz(name)) != 0; 1062 } 1063 1064 /** 1065 * Gets the list of children on @settings. 1066 * 1067 * The list is exactly the list of strings for which it is not an error 1068 * to call g_settings_get_child(). 1069 * 1070 * For GSettings objects that are lists, this value can change at any 1071 * time and you should connect to the "children-changed" signal to watch 1072 * for those changes. Note that there is a race condition here: you may 1073 * request a child after listing it only for it to have been destroyed 1074 * in the meantime. For this reason, g_settings_get_child() may return 1075 * %NULL even for a child that was listed by this function. 1076 * 1077 * For GSettings objects that are not lists, you should probably not be 1078 * calling this function from "normal" code (since you should already 1079 * know what children are in your schema). This function may still be 1080 * useful there for introspection reasons, however. 1081 * 1082 * You should free the return value with g_strfreev() when you are done 1083 * with it. 1084 * 1085 * Return: a list of the children on @settings 1086 */ 1087 public string[] listChildren() 1088 { 1089 return Str.toStringArray(g_settings_list_children(gSettings)); 1090 } 1091 1092 /** 1093 * Introspects the list of keys on @settings. 1094 * 1095 * You should probably not be calling this function from "normal" code 1096 * (since you should already know what keys are in your schema). This 1097 * function is intended for introspection reasons. 1098 * 1099 * You should free the return value with g_strfreev() when you are done 1100 * with it. 1101 * 1102 * Return: a list of the keys on @settings 1103 */ 1104 public string[] listKeys() 1105 { 1106 return Str.toStringArray(g_settings_list_keys(gSettings)); 1107 } 1108 1109 /** 1110 * Checks if the given @value is of the correct type and within the 1111 * permitted range for @key. 1112 * 1113 * Deprecated: Use g_settings_schema_key_range_check() instead. 1114 * 1115 * Params: 1116 * key = the key to check 1117 * value = the value to check 1118 * 1119 * Return: %TRUE if @value is valid for @key 1120 * 1121 * Since: 2.28 1122 */ 1123 public bool rangeCheck(string key, Variant value) 1124 { 1125 return g_settings_range_check(gSettings, Str.toStringz(key), (value is null) ? null : value.getVariantStruct()) != 0; 1126 } 1127 1128 /** 1129 * Resets @key to its default value. 1130 * 1131 * This call resets the key, as much as possible, to its default value. 1132 * That might the value specified in the schema or the one set by the 1133 * administrator. 1134 * 1135 * Params: 1136 * key = the name of a key 1137 */ 1138 public void reset(string key) 1139 { 1140 g_settings_reset(gSettings, Str.toStringz(key)); 1141 } 1142 1143 /** 1144 * Reverts all non-applied changes to the settings. This function 1145 * does nothing unless @settings is in 'delay-apply' mode; see 1146 * g_settings_delay(). In the normal case settings are always applied 1147 * immediately. 1148 * 1149 * Change notifications will be emitted for affected keys. 1150 */ 1151 public void revert() 1152 { 1153 g_settings_revert(gSettings); 1154 } 1155 1156 /** 1157 * Sets @key in @settings to @value. 1158 * 1159 * A convenience variant of g_settings_set() for booleans. 1160 * 1161 * It is a programmer error to give a @key that isn't specified as 1162 * having a boolean type in the schema for @settings. 1163 * 1164 * Params: 1165 * key = the name of the key to set 1166 * value = the value to set it to 1167 * 1168 * Return: %TRUE if setting the key succeeded, 1169 * %FALSE if the key was not writable 1170 * 1171 * Since: 2.26 1172 */ 1173 public bool setBoolean(string key, bool value) 1174 { 1175 return g_settings_set_boolean(gSettings, Str.toStringz(key), value) != 0; 1176 } 1177 1178 /** 1179 * Sets @key in @settings to @value. 1180 * 1181 * A convenience variant of g_settings_set() for doubles. 1182 * 1183 * It is a programmer error to give a @key that isn't specified as 1184 * having a 'double' type in the schema for @settings. 1185 * 1186 * Params: 1187 * key = the name of the key to set 1188 * value = the value to set it to 1189 * 1190 * Return: %TRUE if setting the key succeeded, 1191 * %FALSE if the key was not writable 1192 * 1193 * Since: 2.26 1194 */ 1195 public bool setDouble(string key, double value) 1196 { 1197 return g_settings_set_double(gSettings, Str.toStringz(key), value) != 0; 1198 } 1199 1200 /** 1201 * Looks up the enumerated type nick for @value and writes it to @key, 1202 * within @settings. 1203 * 1204 * It is a programmer error to give a @key that isn't contained in the 1205 * schema for @settings or is not marked as an enumerated type, or for 1206 * @value not to be a valid value for the named type. 1207 * 1208 * After performing the write, accessing @key directly with 1209 * g_settings_get_string() will return the 'nick' associated with 1210 * @value. 1211 * 1212 * Params: 1213 * key = a key, within @settings 1214 * value = an enumerated value 1215 * 1216 * Return: %TRUE, if the set succeeds 1217 */ 1218 public bool setEnum(string key, int value) 1219 { 1220 return g_settings_set_enum(gSettings, Str.toStringz(key), value) != 0; 1221 } 1222 1223 /** 1224 * Looks up the flags type nicks for the bits specified by @value, puts 1225 * them in an array of strings and writes the array to @key, within 1226 * @settings. 1227 * 1228 * It is a programmer error to give a @key that isn't contained in the 1229 * schema for @settings or is not marked as a flags type, or for @value 1230 * to contain any bits that are not value for the named type. 1231 * 1232 * After performing the write, accessing @key directly with 1233 * g_settings_get_strv() will return an array of 'nicks'; one for each 1234 * bit in @value. 1235 * 1236 * Params: 1237 * key = a key, within @settings 1238 * value = a flags value 1239 * 1240 * Return: %TRUE, if the set succeeds 1241 */ 1242 public bool setFlags(string key, uint value) 1243 { 1244 return g_settings_set_flags(gSettings, Str.toStringz(key), value) != 0; 1245 } 1246 1247 /** 1248 * Sets @key in @settings to @value. 1249 * 1250 * A convenience variant of g_settings_set() for 32-bit integers. 1251 * 1252 * It is a programmer error to give a @key that isn't specified as 1253 * having a int32 type in the schema for @settings. 1254 * 1255 * Params: 1256 * key = the name of the key to set 1257 * value = the value to set it to 1258 * 1259 * Return: %TRUE if setting the key succeeded, 1260 * %FALSE if the key was not writable 1261 * 1262 * Since: 2.26 1263 */ 1264 public bool setInt(string key, int value) 1265 { 1266 return g_settings_set_int(gSettings, Str.toStringz(key), value) != 0; 1267 } 1268 1269 /** 1270 * Sets @key in @settings to @value. 1271 * 1272 * A convenience variant of g_settings_set() for strings. 1273 * 1274 * It is a programmer error to give a @key that isn't specified as 1275 * having a string type in the schema for @settings. 1276 * 1277 * Params: 1278 * key = the name of the key to set 1279 * value = the value to set it to 1280 * 1281 * Return: %TRUE if setting the key succeeded, 1282 * %FALSE if the key was not writable 1283 * 1284 * Since: 2.26 1285 */ 1286 public bool setString(string key, string value) 1287 { 1288 return g_settings_set_string(gSettings, Str.toStringz(key), Str.toStringz(value)) != 0; 1289 } 1290 1291 /** 1292 * Sets @key in @settings to @value. 1293 * 1294 * A convenience variant of g_settings_set() for string arrays. If 1295 * @value is %NULL, then @key is set to be the empty array. 1296 * 1297 * It is a programmer error to give a @key that isn't specified as 1298 * having an array of strings type in the schema for @settings. 1299 * 1300 * Params: 1301 * key = the name of the key to set 1302 * value = the value to set it to, or %NULL 1303 * 1304 * Return: %TRUE if setting the key succeeded, 1305 * %FALSE if the key was not writable 1306 * 1307 * Since: 2.26 1308 */ 1309 public bool setStrv(string key, string[] value) 1310 { 1311 return g_settings_set_strv(gSettings, Str.toStringz(key), Str.toStringzArray(value)) != 0; 1312 } 1313 1314 /** 1315 * Sets @key in @settings to @value. 1316 * 1317 * A convenience variant of g_settings_set() for 32-bit unsigned 1318 * integers. 1319 * 1320 * It is a programmer error to give a @key that isn't specified as 1321 * having a uint32 type in the schema for @settings. 1322 * 1323 * Params: 1324 * key = the name of the key to set 1325 * value = the value to set it to 1326 * 1327 * Return: %TRUE if setting the key succeeded, 1328 * %FALSE if the key was not writable 1329 * 1330 * Since: 2.30 1331 */ 1332 public bool setUint(string key, uint value) 1333 { 1334 return g_settings_set_uint(gSettings, Str.toStringz(key), value) != 0; 1335 } 1336 1337 /** 1338 * Sets @key in @settings to @value. 1339 * 1340 * It is a programmer error to give a @key that isn't contained in the 1341 * schema for @settings or for @value to have the incorrect type, per 1342 * the schema. 1343 * 1344 * If @value is floating then this function consumes the reference. 1345 * 1346 * Params: 1347 * key = the name of the key to set 1348 * value = a #GVariant of the correct type 1349 * 1350 * Return: %TRUE if setting the key succeeded, 1351 * %FALSE if the key was not writable 1352 * 1353 * Since: 2.26 1354 */ 1355 public bool setValue(string key, Variant value) 1356 { 1357 return g_settings_set_value(gSettings, Str.toStringz(key), (value is null) ? null : value.getVariantStruct()) != 0; 1358 } 1359 1360 int[string] connectedSignals; 1361 1362 bool delegate(void*, int, Settings)[] onChangeListeners; 1363 /** 1364 * The "change-event" signal is emitted once per change event that 1365 * affects this settings object. You should connect to this signal 1366 * only if you are interested in viewing groups of changes before they 1367 * are split out into multiple emissions of the "changed" signal. 1368 * For most use cases it is more appropriate to use the "changed" signal. 1369 * 1370 * In the event that the change event applies to one or more specified 1371 * keys, @keys will be an array of #GQuark of length @n_keys. In the 1372 * event that the change event applies to the #GSettings object as a 1373 * whole (ie: potentially every key has been changed) then @keys will 1374 * be %NULL and @n_keys will be 0. 1375 * 1376 * The default handler for this signal invokes the "changed" signal 1377 * for each affected key. If any other connected handler returns 1378 * %TRUE then this default functionality will be suppressed. 1379 * 1380 * Params: 1381 * keys = an array of #GQuarks for the changed keys, or %NULL 1382 * nKeys = the length of the @keys array, or 0 1383 * 1384 * Return: %TRUE to stop other handlers from being invoked for the 1385 * event. FALSE to propagate the event further. 1386 */ 1387 void addOnChange(bool delegate(void*, int, Settings) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 1388 { 1389 if ( "change-event" !in connectedSignals ) 1390 { 1391 Signals.connectData( 1392 this, 1393 "change-event", 1394 cast(GCallback)&callBackChange, 1395 cast(void*)this, 1396 null, 1397 connectFlags); 1398 connectedSignals["change-event"] = 1; 1399 } 1400 onChangeListeners ~= dlg; 1401 } 1402 extern(C) static int callBackChange(GSettings* settingsStruct, void* keys, int nKeys, Settings _settings) 1403 { 1404 foreach ( bool delegate(void*, int, Settings) dlg; _settings.onChangeListeners ) 1405 { 1406 if ( dlg(keys, nKeys, _settings) ) 1407 { 1408 return 1; 1409 } 1410 } 1411 1412 return 0; 1413 } 1414 1415 void delegate(string, Settings)[] onChangedListeners; 1416 /** 1417 * The "changed" signal is emitted when a key has potentially changed. 1418 * You should call one of the g_settings_get() calls to check the new 1419 * value. 1420 * 1421 * This signal supports detailed connections. You can connect to the 1422 * detailed signal "changed::x" in order to only receive callbacks 1423 * when key "x" changes. 1424 * 1425 * Params: 1426 * key = the name of the key that changed 1427 */ 1428 void addOnChanged(void delegate(string, Settings) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 1429 { 1430 if ( "changed" !in connectedSignals ) 1431 { 1432 Signals.connectData( 1433 this, 1434 "changed", 1435 cast(GCallback)&callBackChanged, 1436 cast(void*)this, 1437 null, 1438 connectFlags); 1439 connectedSignals["changed"] = 1; 1440 } 1441 onChangedListeners ~= dlg; 1442 } 1443 extern(C) static void callBackChanged(GSettings* settingsStruct, char* key, Settings _settings) 1444 { 1445 foreach ( void delegate(string, Settings) dlg; _settings.onChangedListeners ) 1446 { 1447 dlg(Str.toString(key), _settings); 1448 } 1449 } 1450 1451 bool delegate(uint, Settings)[] onWritableChangeListeners; 1452 /** 1453 * The "writable-change-event" signal is emitted once per writability 1454 * change event that affects this settings object. You should connect 1455 * to this signal if you are interested in viewing groups of changes 1456 * before they are split out into multiple emissions of the 1457 * "writable-changed" signal. For most use cases it is more 1458 * appropriate to use the "writable-changed" signal. 1459 * 1460 * In the event that the writability change applies only to a single 1461 * key, @key will be set to the #GQuark for that key. In the event 1462 * that the writability change affects the entire settings object, 1463 * @key will be 0. 1464 * 1465 * The default handler for this signal invokes the "writable-changed" 1466 * and "changed" signals for each affected key. This is done because 1467 * changes in writability might also imply changes in value (if for 1468 * example, a new mandatory setting is introduced). If any other 1469 * connected handler returns %TRUE then this default functionality 1470 * will be suppressed. 1471 * 1472 * Params: 1473 * key = the quark of the key, or 0 1474 * 1475 * Return: %TRUE to stop other handlers from being invoked for the 1476 * event. FALSE to propagate the event further. 1477 */ 1478 void addOnWritableChange(bool delegate(uint, Settings) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 1479 { 1480 if ( "writable-change-event" !in connectedSignals ) 1481 { 1482 Signals.connectData( 1483 this, 1484 "writable-change-event", 1485 cast(GCallback)&callBackWritableChange, 1486 cast(void*)this, 1487 null, 1488 connectFlags); 1489 connectedSignals["writable-change-event"] = 1; 1490 } 1491 onWritableChangeListeners ~= dlg; 1492 } 1493 extern(C) static int callBackWritableChange(GSettings* settingsStruct, uint key, Settings _settings) 1494 { 1495 foreach ( bool delegate(uint, Settings) dlg; _settings.onWritableChangeListeners ) 1496 { 1497 if ( dlg(key, _settings) ) 1498 { 1499 return 1; 1500 } 1501 } 1502 1503 return 0; 1504 } 1505 1506 void delegate(string, Settings)[] onWritableChangedListeners; 1507 /** 1508 * The "writable-changed" signal is emitted when the writability of a 1509 * key has potentially changed. You should call 1510 * g_settings_is_writable() in order to determine the new status. 1511 * 1512 * This signal supports detailed connections. You can connect to the 1513 * detailed signal "writable-changed::x" in order to only receive 1514 * callbacks when the writability of "x" changes. 1515 * 1516 * Params: 1517 * key = the key 1518 */ 1519 void addOnWritableChanged(void delegate(string, Settings) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 1520 { 1521 if ( "writable-changed" !in connectedSignals ) 1522 { 1523 Signals.connectData( 1524 this, 1525 "writable-changed", 1526 cast(GCallback)&callBackWritableChanged, 1527 cast(void*)this, 1528 null, 1529 connectFlags); 1530 connectedSignals["writable-changed"] = 1; 1531 } 1532 onWritableChangedListeners ~= dlg; 1533 } 1534 extern(C) static void callBackWritableChanged(GSettings* settingsStruct, char* key, Settings _settings) 1535 { 1536 foreach ( void delegate(string, Settings) dlg; _settings.onWritableChangedListeners ) 1537 { 1538 dlg(Str.toString(key), _settings); 1539 } 1540 } 1541 }