gio/: fully remove gioalias hacks
[platform/upstream/glib.git] / gio / gsettings.c
index 5a5ceed..3c7b4fc 100644 (file)
@@ -37,7 +37,6 @@
 
 #include <string.h>
 
-#include "gioalias.h"
 
 #include "strinfo.c"
 
@@ -464,7 +463,7 @@ g_settings_get_property (GObject    *object,
   switch (prop_id)
     {
      case PROP_SCHEMA:
-      g_value_set_object (value, settings->priv->schema);
+      g_value_set_string (value, settings->priv->schema_name);
       break;
 
      case PROP_HAS_UNAPPLIED:
@@ -831,7 +830,7 @@ g_settings_new_with_backend_and_path (const gchar      *schema,
                        NULL);
 }
 
-/* Internal read/write utilities, enum conversion, validation {{{1 */
+/* Internal read/write utilities, enum/flags conversion, validation {{{1 */
 typedef struct
 {
   GSettings *settings;
@@ -839,7 +838,9 @@ typedef struct
 
   GSettingsSchema *schema;
 
-  gboolean is_enum;
+  guint is_flags : 1;
+  guint is_enum  : 1;
+
   const guint32 *strinfo;
   gsize strinfo_length;
 
@@ -879,9 +880,16 @@ g_settings_get_key_info (GSettingsKeyInfo *info,
           break;
 
         case 'e':
-          /* enumerated types... */
+          /* enumerated types... */
           info->is_enum = TRUE;
-        case 'c':
+          goto choice;
+
+        case 'f':
+          /* flags... */
+          info->is_flags = TRUE;
+          goto choice;
+
+        choice: case 'c':
           /* ..., choices, aliases */
           info->strinfo = g_variant_get_fixed_array (data,
                                                      &info->strinfo_length,
@@ -956,7 +964,7 @@ g_settings_range_check (GSettingsKeyInfo *info,
       g_variant_iter_init (&iter, value);
       while (ok && (child = g_variant_iter_next_value (&iter)))
         {
-          ok = g_settings_range_check (info, value);
+          ok = g_settings_range_check (info, child);
           g_variant_unref (child);
         }
 
@@ -992,6 +1000,7 @@ g_settings_range_fixup (GSettingsKeyInfo *info,
       GVariantIter iter;
       GVariant *child;
 
+      g_variant_iter_init (&iter, value);
       g_variant_builder_init (&builder, g_variant_get_type (value));
 
       while ((child = g_variant_iter_next_value (&iter)))
@@ -1123,7 +1132,64 @@ g_settings_from_enum (GSettingsKeyInfo *info,
   if (string == NULL)
     return NULL;
 
-  return g_variant_ref_sink (g_variant_new_string (string));
+  return g_variant_new_string (string);
+}
+
+static guint
+g_settings_to_flags (GSettingsKeyInfo *info,
+                     GVariant         *value)
+{
+  GVariantIter iter;
+  const gchar *flag;
+  guint result;
+
+  result = 0;
+  g_variant_iter_init (&iter, value);
+  while (g_variant_iter_next (&iter, "&s", &flag))
+    {
+      gboolean it_worked;
+      guint flag_value;
+
+      it_worked = strinfo_enum_from_string (info->strinfo,
+                                            info->strinfo_length,
+                                            flag, &flag_value);
+      /* as in g_settings_to_enum() */
+      g_assert (it_worked);
+
+      result |= flag_value;
+    }
+
+  return result;
+}
+
+static GVariant *
+g_settings_from_flags (GSettingsKeyInfo *info,
+                       guint             value)
+{
+  GVariantBuilder builder;
+  gint i;
+
+  g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
+
+  for (i = 0; i < 32; i++)
+    if (value & (1u << i))
+      {
+        const gchar *string;
+
+        string = strinfo_string_from_enum (info->strinfo,
+                                           info->strinfo_length,
+                                           1u << i);
+
+        if (string == NULL)
+          {
+            g_variant_builder_clear (&builder);
+            return NULL;
+          }
+
+        g_variant_builder_add (&builder, "s", string);
+      }
+
+  return g_variant_builder_end (&builder);
 }
 
 /* Public Get/Set API {{{1 (get, get_value, set, set_value, get_mapped) */
@@ -1235,7 +1301,7 @@ g_settings_get_enum (GSettings   *settings,
  * schema for @settings or is not marked as an enumerated type, or for
  * @value not to be a valid value for the named type.
  *
- * After performing the write, accessing @key directly
+ * After performing the write, accessing @key directly with
  * g_settings_get_string() will return the 'nick' associated with
  * @value.
  **/
@@ -1271,7 +1337,118 @@ g_settings_set_enum (GSettings   *settings,
 
   success = g_settings_write_to_backend (&info, variant);
   g_settings_free_key_info (&info);
-  g_variant_unref (variant);
+
+  return success;
+}
+
+/**
+ * g_settings_get_flags:
+ * @settings: a #GSettings object
+ * @key: the key to get the value for
+ * @returns: the flags value
+ *
+ * Gets the value that is stored in @settings for @key and converts it
+ * to the flags value that it represents.
+ *
+ * In order to use this function the type of the value must be an array
+ * of strings and it must be marked in the schema file as an flags type.
+ *
+ * It is a programmer error to give a @key that isn't contained in the
+ * schema for @settings or is not marked as a flags type.
+ *
+ * If the value stored in the configuration database is not a valid
+ * value for the flags type then this function will return the default
+ * value.
+ *
+ * Since: 2.26
+ **/
+guint
+g_settings_get_flags (GSettings   *settings,
+                      const gchar *key)
+{
+  GSettingsKeyInfo info;
+  GVariant *value;
+  guint result;
+
+  g_return_val_if_fail (G_IS_SETTINGS (settings), -1);
+  g_return_val_if_fail (key != NULL, -1);
+
+  g_settings_get_key_info (&info, settings, key);
+
+  if (!info.is_flags)
+    {
+      g_critical ("g_settings_get_flags() called on key `%s' which is not "
+                  "associated with a flags type", info.key);
+      g_settings_free_key_info (&info);
+      return -1;
+    }
+
+  value = g_settings_read_from_backend (&info);
+
+  if (value == NULL)
+    value = g_settings_get_translated_default (&info);
+
+  if (value == NULL)
+    value = g_variant_ref (info.default_value);
+
+  result = g_settings_to_flags (&info, value);
+  g_settings_free_key_info (&info);
+  g_variant_unref (value);
+
+  return result;
+}
+
+/**
+ * g_settings_set_flags:
+ * @settings: a #GSettings object
+ * @key: a key, within @settings
+ * @value: a flags value
+ * @returns: %TRUE, if the set succeeds
+ *
+ * Looks up the flags type nicks for the bits specified by @value, puts
+ * them in an array of strings and writes the array to @key, withing
+ * @settings.
+ *
+ * It is a programmer error to give a @key that isn't contained in the
+ * schema for @settings or is not marked as a flags type, or for @value
+ * to contain any bits that are not value for the named type.
+ *
+ * After performing the write, accessing @key directly with
+ * g_settings_get_strv() will return an array of 'nicks'; one for each
+ * bit in @value.
+ **/
+gboolean
+g_settings_set_flags (GSettings   *settings,
+                      const gchar *key,
+                      guint        value)
+{
+  GSettingsKeyInfo info;
+  GVariant *variant;
+  gboolean success;
+
+  g_return_val_if_fail (G_IS_SETTINGS (settings), FALSE);
+  g_return_val_if_fail (key != NULL, FALSE);
+
+  g_settings_get_key_info (&info, settings, key);
+
+  if (!info.is_flags)
+    {
+      g_critical ("g_settings_set_flags() called on key `%s' which is not "
+                  "associated with a flags type", info.key);
+      return FALSE;
+    }
+
+  if (!(variant = g_settings_from_flags (&info, value)))
+    {
+      g_critical ("g_settings_set_flags(): invalid flags value 0x%08x "
+                  "for key `%s' in schema `%s'.  Doing nothing.",
+                  value, info.key, info.settings->priv->schema_name);
+      g_settings_free_key_info (&info);
+      return FALSE;
+    }
+
+  success = g_settings_write_to_backend (&info, variant);
+  g_settings_free_key_info (&info);
 
   return success;
 }
@@ -1786,8 +1963,8 @@ g_settings_delay (GSettings *settings)
  *
  * Applies any changes that have been made to the settings.  This
  * function does nothing unless @settings is in 'delay-apply' mode;
- * see g_settings_set_delay_apply().  In the normal case settings are
- * always applied immediately.
+ * see g_settings_delay().  In the normal case settings are always
+ * applied immediately.
  **/
 void
 g_settings_apply (GSettings *settings)
@@ -1807,8 +1984,8 @@ g_settings_apply (GSettings *settings)
  *
  * Reverts all non-applied changes to the settings.  This function
  * does nothing unless @settings is in 'delay-apply' mode; see
- * g_settings_set_delay_apply().  In the normal case settings are
- * always applied immediately.
+ * g_settings_delay().  In the normal case settings are always applied
+ * immediately.
  *
  * Change notifications will be emitted for affected keys.
  **/
@@ -2472,7 +2649,5 @@ g_settings_unbind (gpointer     object,
 }
 
 /* Epilogue {{{1 */
-#define __G_SETTINGS_C__
-#include "gioaliasdef.c"
 
 /* vim:set foldmethod=marker: */