Esempio n. 1
0
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
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
/**
 * 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;
}
Esempio n. 6
0
/**
 * 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;
}
Esempio n. 7
0
/**
 * 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;
}
Esempio n. 8
0
/* 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;
    }
}
Esempio n. 9
0
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);
    }
}