static void do_set_value (GConfDefaults *mechanism, gboolean mandatory, const char *path, const char *value, DBusGMethodInvocation *context, GConfChangeSet **changeset_out) { GConfClient *dest = NULL; GConfChangeSet *changes = NULL; GConfEngine *engine; GConfValue *gvalue; GError *error; GError *error2; const char *action; const char *annotation_key; const char *default_action; const char *dest_address; if (changeset_out) *changeset_out = NULL; stop_killtimer (); if (mandatory) { annotation_key = "org.gnome.gconf.defaults.set-mandatory.prefix"; default_action = "org.gnome.gconf.defaults.set-mandatory"; dest_address = "xml:merged:/etc/gconf/gconf.xml.mandatory"; } else { annotation_key = "org.gnome.gconf.defaults.set-system.prefix"; default_action = "org.gnome.gconf.defaults.set-system"; dest_address = "xml:merged:/etc/gconf/gconf.xml.system"; } action = polkit_action_for_gconf_path (mechanism, annotation_key, path); if (action == NULL) action = default_action; if (!check_polkit_for_action (mechanism, context, action)) goto out; error = NULL; engine = gconf_engine_get_local (dest_address, &error); if (error) goto cleanup; dest = gconf_client_get_for_engine (engine); gconf_engine_unref (engine); changes = gconf_change_set_new (); gvalue = gconf_value_decode (value); if (!gvalue) goto cleanup; gconf_change_set_set (changes, path, gvalue); gconf_value_free (gvalue); gconf_client_commit_change_set (dest, changes, FALSE, &error); gconf_client_suggest_sync (dest, NULL); if (changeset_out) { *changeset_out = changes; changes = NULL; } cleanup: if (changes) gconf_change_set_unref (changes); if (dest) g_object_unref (dest); if (error) { g_print ("failed to set GConf values: %s\n", error->message); error2 = g_error_new_literal (GCONF_DEFAULTS_ERROR, GCONF_DEFAULTS_ERROR_GENERAL, error->message); g_error_free (error); dbus_g_method_return_error (context, error2); g_error_free (error2); } else dbus_g_method_return (context); out: start_killtimer (); }
gboolean window_list_applet_fill (PanelApplet *applet) { TasklistData *tasklist; GError *error; GConfValue *value; tasklist = g_new0 (TasklistData, 1); tasklist->applet = GTK_WIDGET (applet); panel_applet_set_flags (PANEL_APPLET (tasklist->applet), PANEL_APPLET_EXPAND_MAJOR | PANEL_APPLET_EXPAND_MINOR | PANEL_APPLET_HAS_HANDLE); panel_applet_add_preferences (applet, "/schemas/apps/window_list_applet/prefs", NULL); setup_gconf (tasklist); error = NULL; tasklist->include_all_workspaces = panel_applet_gconf_get_bool (applet, "display_all_workspaces", &error); if (error) { g_error_free (error); tasklist->include_all_workspaces = FALSE; /* Default value */ } error = NULL; tasklist->grouping = -1; value = panel_applet_gconf_get_value (applet, "group_windows", &error); if (error) { g_error_free (error); } else if (value) { tasklist->grouping = get_grouping_type (value); gconf_value_free (value); } if (tasklist->grouping < 0) tasklist->grouping = WNCK_TASKLIST_AUTO_GROUP; /* Default value */ error = NULL; tasklist->move_unminimized_windows = panel_applet_gconf_get_bool (applet, "move_unminimized_windows", &error); if (error) { g_error_free (error); tasklist->move_unminimized_windows = TRUE; /* Default value */ } tasklist->size = panel_applet_get_size (applet); switch (panel_applet_get_orient (applet)) { case PANEL_APPLET_ORIENT_LEFT: case PANEL_APPLET_ORIENT_RIGHT: tasklist->orientation = GTK_ORIENTATION_VERTICAL; break; case PANEL_APPLET_ORIENT_UP: case PANEL_APPLET_ORIENT_DOWN: default: tasklist->orientation = GTK_ORIENTATION_HORIZONTAL; break; } tasklist->tasklist = wnck_tasklist_new (NULL); wnck_tasklist_set_icon_loader (WNCK_TASKLIST (tasklist->tasklist), icon_loader_func, tasklist, NULL); g_signal_connect (G_OBJECT (tasklist->tasklist), "destroy", G_CALLBACK (destroy_tasklist), tasklist); g_signal_connect (G_OBJECT (tasklist->applet), "size_request", G_CALLBACK (applet_size_request), tasklist); tasklist_update (tasklist); gtk_widget_show (tasklist->tasklist); gtk_container_add (GTK_CONTAINER (tasklist->applet), tasklist->tasklist); g_signal_connect (G_OBJECT (tasklist->applet), "realize", G_CALLBACK (applet_realized), tasklist); g_signal_connect (G_OBJECT (tasklist->applet), "change_orient", G_CALLBACK (applet_change_orient), tasklist); g_signal_connect (G_OBJECT (tasklist->applet), "change_size", G_CALLBACK (applet_change_pixel_size), tasklist); g_signal_connect (G_OBJECT (tasklist->applet), "change_background", G_CALLBACK (applet_change_background), tasklist); panel_applet_set_background_widget (PANEL_APPLET (tasklist->applet), GTK_WIDGET (tasklist->applet)); panel_applet_setup_menu_from_file (PANEL_APPLET (tasklist->applet), NULL, "GNOME_WindowListApplet.xml", NULL, tasklist_menu_verbs, tasklist); if (panel_applet_get_locked_down (PANEL_APPLET (tasklist->applet))) { BonoboUIComponent *popup_component; popup_component = panel_applet_get_popup_component (PANEL_APPLET (tasklist->applet)); bonobo_ui_component_set_prop (popup_component, "/commands/TasklistPreferences", "hidden", "1", NULL); } gtk_widget_show (tasklist->applet); return TRUE; }
static void dasher_app_settings_load(DasherAppSettings *pSelf) { #ifdef WITH_GCONF DasherAppSettingsPrivate *pPrivate = (DasherAppSettingsPrivate *)(pSelf->private_data); GError *pGConfError = NULL; GConfValue *pGConfValue; for(int i(0); i < NUM_OF_APP_BPS; ++i ) { if(app_boolparamtable[i].persistent) { gchar szName[256]; strncpy(szName, "/apps/dasher4/", 256); strncat(szName, app_boolparamtable[i].regName, 255 - strlen( szName )); pGConfValue = gconf_client_get_without_default(pPrivate->pGConfClient, szName, &pGConfError); if(pGConfValue) { app_boolparamtable[i].value = gconf_value_get_bool(pGConfValue); gconf_value_free(pGConfValue); } } } for(int i(0); i < NUM_OF_APP_LPS; ++i ) { if(app_longparamtable[i].persistent) { gchar szName[256]; strncpy(szName, "/apps/dasher4/", 256); strncat(szName, app_longparamtable[i].regName, 255 - strlen( szName )); pGConfValue = gconf_client_get_without_default(pPrivate->pGConfClient, szName, &pGConfError); if(pGConfValue) { app_longparamtable[i].value = gconf_value_get_int(pGConfValue); gconf_value_free(pGConfValue); } } } for(int i(0); i < NUM_OF_APP_SPS; ++i ) { if(app_stringparamtable[i].persistent) { gchar szName[256]; strncpy(szName, "/apps/dasher4/", 256); strncat(szName, app_stringparamtable[i].regName, 255 - strlen( szName )); pGConfValue = gconf_client_get_without_default(pPrivate->pGConfClient, szName, &pGConfError); if(pGConfValue) { delete[] app_stringparamtable[i].value; const gchar *szValue(gconf_value_get_string(pGConfValue)); gchar *szNew; szNew = new gchar[strlen(szValue) + 1]; strcpy(szNew, szValue); app_stringparamtable[i].value = szNew; gconf_value_free(pGConfValue); } } } #endif }
static gboolean handle_file (const gchar *filename) { GKeyFile *keyfile; GConfClient *client; GConfValue *value; gint i, j; gchar *gconf_key; gchar **groups; gchar **keys; GVariantBuilder *builder; GVariant *v; const gchar *s; gchar *str; gint ii; GSList *list, *l; GSettingsSchemaSource *source; GSettingsSchema *schema; GSettings *settings; GError *error; keyfile = g_key_file_new (); error = NULL; if (!g_key_file_load_from_file (keyfile, filename, 0, &error)) { if (verbose) g_printerr ("%s: %s\n", filename, error->message); g_error_free (error); g_key_file_free (keyfile); return FALSE; } client = get_writable_client (); source = g_settings_schema_source_get_default (); groups = g_key_file_get_groups (keyfile, NULL); for (i = 0; groups[i]; i++) { gchar **schema_path; schema_path = g_strsplit (groups[i], ":", 2); schema = g_settings_schema_source_lookup (source, schema_path[0], TRUE); if (schema == NULL) { if (verbose) { g_print ("Schema '%s' not found, skipping\n", schema_path[0]); } g_strfreev (schema_path); continue; } g_settings_schema_unref (schema); if (verbose) { g_print ("Collecting settings for schema '%s'\n", schema_path[0]); if (schema_path[1]) g_print ("for storage at '%s'\n", schema_path[1]); } if (schema_path[1] != NULL) settings = g_settings_new_with_path (schema_path[0], schema_path[1]); else settings = g_settings_new (schema_path[0]); g_settings_delay (settings); error = NULL; if ((keys = g_key_file_get_keys (keyfile, groups[i], NULL, &error)) == NULL) { g_printerr ("%s", error->message); g_error_free (error); continue; } for (j = 0; keys[j]; j++) { if (strchr (keys[j], '/') != 0) { g_printerr ("Key '%s' contains a '/'\n", keys[j]); continue; } error = NULL; if ((gconf_key = g_key_file_get_string (keyfile, groups[i], keys[j], &error)) == NULL) { g_printerr ("%s", error->message); g_error_free (error); continue; } error = NULL; if ((value = gconf_client_get_without_default (client, gconf_key, &error)) == NULL) { if (error) { g_printerr ("Failed to get GConf key '%s': %s\n", gconf_key, error->message); g_error_free (error); } else { if (verbose) g_print ("Skipping GConf key '%s', no user value\n", gconf_key); } g_free (gconf_key); continue; } switch (value->type) { case GCONF_VALUE_STRING: if (dry_run) g_print ("Set key '%s' to string '%s'\n", keys[j], gconf_value_get_string (value)); else g_settings_set (settings, keys[j], "s", gconf_value_get_string (value)); break; case GCONF_VALUE_INT: if (dry_run) g_print ("Set key '%s' to integer '%d'\n", keys[j], gconf_value_get_int (value)); else { GVariant *range; gchar *type; range = g_settings_get_range (settings, keys[j]); g_variant_get (range, "(&sv)", &type, NULL); if (strcmp (type, "enum") == 0) g_settings_set_enum (settings, keys[j], gconf_value_get_int (value)); else if (strcmp (type, "flags") == 0) g_settings_set_flags (settings, keys[j], gconf_value_get_int (value)); else if (type_uint32 (settings, keys[j])) g_settings_set (settings, keys[j], "u", gconf_value_get_int (value)); else g_settings_set (settings, keys[j], "i", gconf_value_get_int (value)); g_variant_unref (range); } break; case GCONF_VALUE_BOOL: if (dry_run) g_print ("Set key '%s' to boolean '%d'\n", keys[j], gconf_value_get_bool (value)); else g_settings_set (settings, keys[j], "b", gconf_value_get_bool (value)); break; case GCONF_VALUE_FLOAT: if (dry_run) g_print ("Set key '%s' to double '%g'\n", keys[j], gconf_value_get_float (value)); else g_settings_set (settings, keys[j], "d", gconf_value_get_float (value)); break; case GCONF_VALUE_LIST: switch (gconf_value_get_list_type (value)) { case GCONF_VALUE_STRING: builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY); list = gconf_value_get_list (value); if (list != NULL) { for (l = list; l; l = l->next) { GConfValue *lv = l->data; s = gconf_value_get_string (lv); g_variant_builder_add (builder, "s", s); } v = g_variant_new ("as", builder); } else v = g_variant_new_array (G_VARIANT_TYPE_STRING, NULL, 0); g_variant_ref_sink (v); if (dry_run) { str = g_variant_print (v, FALSE); g_print ("Set key '%s' to a list of strings: %s\n", keys[j], str); g_free (str); } else g_settings_set_value (settings, keys[j], v); g_variant_unref (v); g_variant_builder_unref (builder); break; case GCONF_VALUE_INT: builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY); list = gconf_value_get_list (value); if (list != NULL) { for (l = list; l; l = l->next) { GConfValue *lv = l->data; ii = gconf_value_get_int (lv); g_variant_builder_add (builder, "i", ii); } v = g_variant_new ("ai", builder); } else v = g_variant_new_array (G_VARIANT_TYPE_INT32, NULL, 0); g_variant_ref_sink (v); if (dry_run) { str = g_variant_print (v, FALSE); g_print ("Set key '%s' to a list of integers: %s\n", keys[j], str); g_free (str); } else g_settings_set_value (settings, keys[j], v); g_variant_unref (v); g_variant_builder_unref (builder); break; default: g_printerr ("Keys of type 'list of %s' not handled yet\n", gconf_value_type_to_string (gconf_value_get_list_type (value))); break; } break; default: g_printerr ("Keys of type %s not handled yet\n", gconf_value_type_to_string (value->type)); break; } gconf_value_free (value); g_free (gconf_key); } g_strfreev (keys); if (!dry_run) g_settings_apply (settings); g_object_unref (settings); g_strfreev (schema_path); } g_strfreev (groups); g_object_unref (client); return TRUE; }
/** * gconf_bridge_bind_window * @bridge: A #GConfBridge * @key_prefix: The prefix of the GConf keys * @window: A #GtkWindow * @bind_size: TRUE to bind the size of @window * @bind_pos: TRUE to bind the position of @window * * On calling this function @window will be resized to the values * specified by "@key_prefix<!-- -->_width" and "@key_prefix<!-- -->_height" * and maximixed if "@key_prefix<!-- -->_maximized is TRUE if * @bind_size is TRUE, and moved to the values specified by * "@key_prefix<!-- -->_x" and "@key_prefix<!-- -->_y" if @bind_pos is TRUE. * The respective GConf values will be updated when the window is resized * and/or moved. * * Return value: The ID of the new binding. **/ guint gconf_bridge_bind_window (GConfBridge *bridge, const gchar *key_prefix, GtkWindow *window, gboolean bind_size, gboolean bind_pos) { WindowBinding *binding; g_return_val_if_fail (bridge != NULL, 0); g_return_val_if_fail (key_prefix != NULL, 0); g_return_val_if_fail (GTK_IS_WINDOW (window), 0); /* Create new binding. */ binding = g_new (WindowBinding, 1); binding->type = BINDING_WINDOW; binding->id = new_id (); binding->bind_size = bind_size; binding->bind_pos = bind_pos; binding->key_prefix = g_strdup (key_prefix); binding->window = window; binding->sync_timeout_id = 0; /* Set up GConf keys & sync window to GConf values */ if (bind_size) { gchar *key; GConfValue *width_val, *height_val, *maximized_val; key = g_strconcat (key_prefix, "_width", NULL); width_val = gconf_client_get (bridge->client, key, NULL); g_free (key); key = g_strconcat (key_prefix, "_height", NULL); height_val = gconf_client_get (bridge->client, key, NULL); g_free (key); key = g_strconcat (key_prefix, "_maximized", NULL); maximized_val = gconf_client_get (bridge->client, key, NULL); g_free (key); if (width_val && height_val) { gtk_window_resize (window, gconf_value_get_int (width_val), gconf_value_get_int (height_val)); gconf_value_free (width_val); gconf_value_free (height_val); } else if (width_val) { gconf_value_free (width_val); } else if (height_val) { gconf_value_free (height_val); } if (maximized_val) { if (gconf_value_get_bool (maximized_val)) { /* Maximize is not done immediately, but to * count with proper window size, resize it * before. The previous size is restored * after the maximization is changed, * in window_binding_state_event_cb(). */ gint width = 0, height = 0; GdkScreen *screen; gtk_window_get_size (window, &width, &height); g_object_set_data ( G_OBJECT (window), "binding-premax-width", GINT_TO_POINTER (width)); g_object_set_data ( G_OBJECT (window), "binding-premax-height", GINT_TO_POINTER (height)); screen = gtk_window_get_screen (window); gtk_window_resize (window, gdk_screen_get_width (screen), gdk_screen_get_height (screen)); gtk_window_maximize (window); } gconf_value_free (maximized_val); } } if (bind_pos) { gchar *key; GConfValue *x_val, *y_val; key = g_strconcat (key_prefix, "_x", NULL); x_val = gconf_client_get (bridge->client, key, NULL); g_free (key); key = g_strconcat (key_prefix, "_y", NULL); y_val = gconf_client_get (bridge->client, key, NULL); g_free (key); if (x_val && y_val) { gtk_window_move (window, gconf_value_get_int (x_val), gconf_value_get_int (y_val)); gconf_value_free (x_val); gconf_value_free (y_val); } else if (x_val) { gconf_value_free (x_val); } else if (y_val) { gconf_value_free (y_val); } } /* Connect to window size change notifications */ binding->configure_event_id = g_signal_connect (window, "configure-event", G_CALLBACK (window_binding_configure_event_cb), binding); binding->window_state_event_id = g_signal_connect (window, "window_state_event", G_CALLBACK (window_binding_state_event_cb), binding); binding->unmap_id = g_signal_connect (window, "unmap", G_CALLBACK (window_binding_unmap_cb), binding); /* Handle case where window gets destroyed */ g_object_weak_ref (G_OBJECT (window), window_binding_window_destroyed, binding); /* Insert binding */ g_hash_table_insert (bridge->bindings, GUINT_TO_POINTER (binding->id), binding); /* Done */ return binding->id; }
/** * gconf_bridge_bind_property_full * @bridge: A #GConfBridge * @key: A GConf key to be bound * @object: A #GObject * @prop: The property of @object to be bound * @delayed_sync: TRUE if there should be a delay between property changes * and syncs to GConf. Set to TRUE when binding to a rapidly-changing * property, for example the "value" property on a #GtkAdjustment. * * Binds @key to @prop, causing them to have the same value at all times. * * The types of @key and @prop should be compatible. Floats and doubles, and * ints, uints, longs, unlongs, int64s, uint64s, chars, uchars and enums * can be matched up. Booleans and strings can only be matched to their * respective types. * * On calling this function the current value of @key will be set to @prop. * * Return value: The ID of the new binding. **/ guint gconf_bridge_bind_property_full (GConfBridge *bridge, const gchar *key, GObject *object, const gchar *prop, gboolean delayed_sync) { GParamSpec *pspec; PropBinding *binding; gchar *signal; GConfValue *val; g_return_val_if_fail (bridge != NULL, 0); g_return_val_if_fail (key != NULL, 0); g_return_val_if_fail (G_IS_OBJECT (object), 0); g_return_val_if_fail (prop != NULL, 0); /* First, try to fetch the propertys GParamSpec off the object */ pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), prop); if (G_UNLIKELY (pspec == NULL)) { g_warning ("gconf_bridge_bind_property_full: A property \"%s\" " "was not found. Please make sure you are passing " "the right property name.", prop); return 0; } /* GParamSpec found: All good, create new binding. */ binding = g_new (PropBinding, 1); binding->type = BINDING_PROP; binding->id = new_id (); binding->delayed_mode = delayed_sync; binding->val_changes = NULL; binding->key = g_strdup (key); binding->object = object; binding->prop = pspec; binding->sync_timeout_id = 0; /* Watch GConf key */ binding->val_notify_id = gconf_client_notify_add (bridge->client, key, prop_binding_pref_changed, binding, NULL, NULL); /* Connect to property change notifications */ signal = g_strconcat ("notify::", prop, NULL); binding->prop_notify_id = g_signal_connect (object, signal, G_CALLBACK (prop_binding_prop_changed), binding); g_free (signal); /* Sync object to value from GConf, if set */ val = gconf_client_get (bridge->client, key, NULL); if (val) { prop_binding_sync_pref_to_prop (binding, val); gconf_value_free (val); } /* Handle case where watched object gets destroyed */ g_object_weak_ref (object, prop_binding_object_destroyed, binding); /* Insert binding */ g_hash_table_insert (bridge->bindings, GUINT_TO_POINTER (binding->id), binding); /* Done */ return binding->id; }
/** * gconf_bridge_bind_string_list_store * @bridge: A #GConfBridge * @key: A GConf key to be bound * @list_store: A #GtkListStore * * On calling this function single string column #GtkListStore @list_store * will be kept synchronized with the GConf string list value pointed to by * @key. On calling this function @list_store will be populated with the * strings specified by the value of @key. * * Return value: The ID of the new binding. **/ guint gconf_bridge_bind_string_list_store (GConfBridge *bridge, const gchar *key, GtkListStore *list_store) { GtkTreeModel *tree_model; gboolean have_one_column, is_string_column; ListStoreBinding *binding; GConfValue *val; g_return_val_if_fail (bridge != NULL, 0); g_return_val_if_fail (key != NULL, 0); g_return_val_if_fail (GTK_IS_LIST_STORE (list_store), 0); /* Check list store suitability */ tree_model = GTK_TREE_MODEL (list_store); have_one_column = (gtk_tree_model_get_n_columns (tree_model) == 1); is_string_column = (gtk_tree_model_get_column_type (tree_model, 0) == G_TYPE_STRING); if (G_UNLIKELY (!have_one_column || !is_string_column)) { g_warning ("gconf_bridge_bind_string_list_store: Only " "GtkListStores with exactly one string column are " "supported."); return 0; } /* Create new binding. */ binding = g_new (ListStoreBinding, 1); binding->type = BINDING_LIST_STORE; binding->id = new_id (); binding->key = g_strdup (key); binding->val_changes = NULL; binding->list_store = list_store; binding->sync_idle_id = 0; /* Watch GConf key */ binding->val_notify_id = gconf_client_notify_add (bridge->client, key, list_store_binding_pref_changed, binding, NULL, NULL); /* Connect to ListStore change notifications */ binding->row_inserted_id = g_signal_connect_swapped (list_store, "row-inserted", G_CALLBACK (list_store_binding_store_changed_cb), binding); binding->row_changed_id = g_signal_connect_swapped (list_store, "row-changed", G_CALLBACK (list_store_binding_store_changed_cb), binding); binding->row_deleted_id = g_signal_connect_swapped (list_store, "row-deleted", G_CALLBACK (list_store_binding_store_changed_cb), binding); binding->rows_reordered_id = g_signal_connect_swapped (list_store, "rows-reordered", G_CALLBACK (list_store_binding_store_changed_cb), binding); /* Sync object to value from GConf, if set */ val = gconf_client_get (bridge->client, key, NULL); if (val) { list_store_binding_sync_pref_to_store (binding, val); gconf_value_free (val); } /* Handle case where watched object gets destroyed */ g_object_weak_ref (G_OBJECT (list_store), list_store_binding_store_destroyed, binding); /* Insert binding */ g_hash_table_insert (bridge->bindings, GUINT_TO_POINTER (binding->id), binding); /* Done */ return binding->id; }
/* this actually works on any node, not just <entry>, such as the <car> and <cdr> nodes and the <li> nodes and the <default> node */ static GConfValue* node_extract_value(xmlNodePtr node, const gchar** locales, GError** err) { GConfValue* value = NULL; gchar* type_str; GConfValueType type = GCONF_VALUE_INVALID; const gchar* default_locales[] = { "C", NULL }; if (locales == NULL) locales = default_locales; type_str = my_xmlGetProp(node, "type"); if (type_str == NULL) { gconf_set_error(err, GCONF_ERROR_PARSE_ERROR, _("No \"type\" attribute for <%s> node"), (node->name ? (char*)node->name : "(nil)")); return NULL; } type = gconf_value_type_from_string(type_str); xmlFree(type_str); switch (type) { case GCONF_VALUE_INVALID: { gconf_set_error(err, GCONF_ERROR_PARSE_ERROR, _("A node has unknown \"type\" attribute `%s', ignoring"), type_str); return NULL; } break; case GCONF_VALUE_INT: case GCONF_VALUE_BOOL: case GCONF_VALUE_FLOAT: { gchar* value_str; value_str = my_xmlGetProp(node, "value"); if (value_str == NULL) { gconf_set_error(err, GCONF_ERROR_PARSE_ERROR, _("No \"value\" attribute for node")); return NULL; } value = gconf_value_new_from_string(type, value_str, err); xmlFree(value_str); g_return_val_if_fail( (value != NULL) || (err == NULL) || (*err != NULL), NULL ); return value; } break; case GCONF_VALUE_STRING: { xmlNodePtr iter; iter = node->xmlChildrenNode; while (iter != NULL) { if (iter->type == XML_ELEMENT_NODE) { GConfValue* v = NULL; if (strcmp((char *)iter->name, "stringvalue") == 0) { gchar* s; s = (gchar *)xmlNodeGetContent(iter); v = gconf_value_new(GCONF_VALUE_STRING); /* strdup() caused purely by g_free()/free() difference */ gconf_value_set_string(v, s ? s : ""); if (s) xmlFree(s); return v; } else { /* What the hell is this? */ gconf_log(GCL_WARNING, _("Didn't understand XML node <%s> inside an XML list node"), iter->name ? iter->name : (guchar*)"???"); } } iter = iter->next; } return NULL; } break; case GCONF_VALUE_SCHEMA: return schema_node_extract_value(node, locales); break; case GCONF_VALUE_LIST: { xmlNodePtr iter; GSList* values = NULL; GConfValueType list_type = GCONF_VALUE_INVALID; { gchar* s; s = my_xmlGetProp(node, "ltype"); if (s != NULL) { list_type = gconf_value_type_from_string(s); xmlFree(s); } } switch (list_type) { case GCONF_VALUE_INVALID: case GCONF_VALUE_LIST: case GCONF_VALUE_PAIR: gconf_set_error(err, GCONF_ERROR_PARSE_ERROR, _("Invalid type (list, pair, or unknown) in a list node")); return NULL; default: break; } iter = node->xmlChildrenNode; while (iter != NULL) { if (iter->type == XML_ELEMENT_NODE) { GConfValue* v = NULL; if (strcmp((char*)iter->name, "li") == 0) { v = node_extract_value(iter, locales, err); if (v == NULL) { if (err && *err) { gconf_log(GCL_WARNING, _("Bad XML node: %s"), (*err)->message); /* avoid pile-ups */ g_clear_error(err); } } else if (v->type != list_type) { gconf_log(GCL_WARNING, _("List contains a badly-typed node (%s, should be %s)"), gconf_value_type_to_string(v->type), gconf_value_type_to_string(list_type)); gconf_value_free(v); v = NULL; } } else { /* What the hell is this? */ gconf_log(GCL_WARNING, _("Didn't understand XML node <%s> inside an XML list node"), iter->name ? iter->name : (guchar*)"???"); } if (v != NULL) values = g_slist_prepend(values, v); } iter = iter->next; } /* put them in order, set the value */ values = g_slist_reverse(values); value = gconf_value_new(GCONF_VALUE_LIST); gconf_value_set_list_type(value, list_type); gconf_value_set_list_nocopy(value, values); return value; } break; case GCONF_VALUE_PAIR: { GConfValue* car = NULL; GConfValue* cdr = NULL; xmlNodePtr iter; iter = node->xmlChildrenNode; while (iter != NULL) { if (iter->type == XML_ELEMENT_NODE) { if (car == NULL && strcmp((char *)iter->name, "car") == 0) { car = node_extract_value(iter, locales, err); if (car == NULL) { if (err && *err) { gconf_log(GCL_WARNING, _("Ignoring bad car from XML pair: %s"), (*err)->message); /* prevent pile-ups */ g_clear_error(err); } } else if (car->type == GCONF_VALUE_LIST || car->type == GCONF_VALUE_PAIR) { gconf_log(GCL_WARNING, _("parsing XML file: lists and pairs may not be placed inside a pair")); gconf_value_free(car); car = NULL; } } else if (cdr == NULL && strcmp((char *)iter->name, "cdr") == 0) { cdr = node_extract_value(iter, locales, err); if (cdr == NULL) { if (err && *err) { gconf_log(GCL_WARNING, _("Ignoring bad cdr from XML pair: %s"), (*err)->message); /* avoid pile-ups */ g_clear_error(err); } } else if (cdr->type == GCONF_VALUE_LIST || cdr->type == GCONF_VALUE_PAIR) { gconf_log(GCL_WARNING, _("parsing XML file: lists and pairs may not be placed inside a pair")); gconf_value_free(cdr); cdr = NULL; } } else { /* What the hell is this? */ gconf_log(GCL_WARNING, _("Didn't understand XML node <%s> inside an XML pair node"), iter->name ? (gchar*)iter->name : "???"); } } iter = iter->next; } /* Return the pair if we got both halves */ if (car && cdr) { value = gconf_value_new(GCONF_VALUE_PAIR); gconf_value_set_car_nocopy(value, car); gconf_value_set_cdr_nocopy(value, cdr); return value; } else { gconf_log(GCL_WARNING, _("Didn't find car and cdr for XML pair node")); if (car) { g_assert(cdr == NULL); gconf_value_free(car); gconf_set_error(err, GCONF_ERROR_PARSE_ERROR, _("Missing cdr from pair of values in XML file")); } else if (cdr) { g_assert(car == NULL); gconf_value_free(cdr); gconf_set_error(err, GCONF_ERROR_PARSE_ERROR, _("Missing car from pair of values in XML file")); } else { gconf_set_error(err, GCONF_ERROR_PARSE_ERROR, _("Missing both car and cdr values from pair in XML file")); } return NULL; } } break; default: g_assert_not_reached(); return NULL; break; } }
void entry_fill_from_node(Entry* e) { gchar* tmp; GError* error = NULL; g_return_if_fail(e->node != NULL); tmp = my_xmlGetProp(e->node, "schema"); if (tmp != NULL) { /* Filter any crap schemas that appear, some speed cost */ gchar* why_bad = NULL; if (gconf_valid_key(tmp, &why_bad)) { g_assert(why_bad == NULL); e->schema_name = g_strdup(tmp); } else { e->schema_name = NULL; gconf_log(GCL_WARNING, _("Ignoring schema name `%s', invalid: %s"), tmp, why_bad); g_free(why_bad); } xmlFree(tmp); } tmp = my_xmlGetProp(e->node, "mtime"); if (tmp != NULL) { e->mod_time = gconf_string_to_gulong(tmp); xmlFree(tmp); } else e->mod_time = 0; tmp = my_xmlGetProp(e->node, "muser"); if (tmp != NULL) { e->mod_user = g_strdup(tmp); xmlFree(tmp); } else e->mod_user = NULL; entry_sync_if_needed(e); if (e->cached_value != NULL) gconf_value_free(e->cached_value); e->cached_value = node_extract_value(e->node, NULL, /* FIXME current locale as a guess */ &error); if (e->cached_value) { g_return_if_fail(error == NULL); return; } else if (error != NULL) { /* Ignore errors from node_extract_value() if we got a schema name, * since the node's only purpose may be to store the schema name. */ if (e->schema_name == NULL) gconf_log (GCL_WARNING, _("Ignoring XML node `%s': %s"), e->name, error->message); g_error_free(error); } }