[netspeed/unstable] Implement all setting-properties; implement loading/storing them to gconf; hook up the settings-dial



commit 01239a14db6159d99dce9427cebee8f658a19604
Author: Jörgen Scheibengruber <mfcn gmx de>
Date:   Thu Jun 17 00:51:47 2010 +0300

    Implement all setting-properties; implement loading/storing them to gconf; hook up the settings-dialog to use the new properties

 configure.in          |    2 +-
 src/netspeed.c        |   39 ++++++-
 src/settings-dialog.c |  182 +++++++++++++--------------
 src/settings.c        |  326 ++++++++++++++++++++++++++++++++++++++++++++++---
 src/settings.h        |    1 +
 5 files changed, 435 insertions(+), 115 deletions(-)
---
diff --git a/configure.in b/configure.in
index 1dd849e..2035c5d 100644
--- a/configure.in
+++ b/configure.in
@@ -20,7 +20,7 @@ GETTEXT_PACKAGE=netspeed_applet
 AC_SUBST(GETTEXT_PACKAGE)
 AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE", GETTEXT_PACKAGE)
 
-PKG_CHECK_MODULES(NETSPEED, libpanelapplet-2.0 libgtop-2.0 >= 2.14.2)
+PKG_CHECK_MODULES(NETSPEED, libpanelapplet-2.0 gconf-2.0 libgtop-2.0 >= 2.14.2)
 
 AC_SUBST(NETSPEED_APPLET_CFLAGS)
 AC_SUBST(NETSPEED_APPLET_LIBS)
diff --git a/src/netspeed.c b/src/netspeed.c
index f9962ec..256bc4f 100644
--- a/src/netspeed.c
+++ b/src/netspeed.c
@@ -866,6 +866,23 @@ about_cb(BonoboUIComponent *uic, gpointer data, const gchar *verbname)
 	
 }
 
+/* Handle preference dialog response event
+ */
+static void
+pref_response_cb (GtkDialog *dialog, gint id, gpointer data)
+{
+    NetspeedApplet *applet = data;
+  
+    if(id == GTK_RESPONSE_HELP){
+        display_help (GTK_WIDGET (dialog), "netspeed_applet-settings");
+	return;
+    }
+
+    gtk_widget_destroy(GTK_WIDGET(applet->settings_dialog));
+    applet->settings_dialog = NULL;
+}
+
+
 /* Creates the settings dialog
  * After its been closed, take the new values and store
  * them in the gconf database
@@ -882,6 +899,8 @@ settings_cb(BonoboUIComponent *uic, gpointer data, const gchar *verbname)
 		return;
 	}
 	applet->settings_dialog = settings_dialog_new (priv->settings);
+	g_signal_connect(G_OBJECT (applet->settings_dialog), "response",
+			 G_CALLBACK(pref_response_cb), applet);
 
 	gtk_widget_show_all (GTK_WIDGET(applet->settings_dialog));
 }
@@ -1325,7 +1344,6 @@ netspeed_init (Netspeed *self)
 
 	gtk_widget_set_name (GTK_WIDGET(self), "PanelApplet");
 	
-	priv->settings = settings_new();
 	/* Alloc the applet. The "NULL-setting" is really redudant
  	 * but aren't we paranoid?
 	 */
@@ -1462,6 +1480,8 @@ netspeed_factory (PanelApplet *applet, const gchar *iid, gpointer data)
 {
 	NetspeedPrivate *priv;
 	char* menu_string;
+	char* dummy_key, *dummy;
+	char* gconf_path;
 
 	g_return_val_if_fail (IS_NETSPEED (applet), FALSE);
 	priv = NETSPEED (applet)->priv;
@@ -1475,7 +1495,6 @@ netspeed_factory (PanelApplet *applet, const gchar *iid, gpointer data)
                             (gpointer)priv->stuff);
 	g_free (menu_string);
 
-
 	/* Get stored settings from the gconf database
 	 */
 	if (panel_applet_gconf_get_bool(applet, "have_settings", NULL))
@@ -1519,7 +1538,21 @@ netspeed_factory (PanelApplet *applet, const gchar *iid, gpointer data)
 			g_free(tmp);
 		}
 	}
-	
+
+	dummy_key = panel_applet_gconf_get_full_key (applet, "dummy");
+	dummy = dummy_key ? strstr (dummy_key, "dummy") : NULL;
+	if (dummy) {
+		dummy[0] = 0;
+		gconf_path = dummy_key;
+		priv->settings = settings_new_with_gconf_path (gconf_path);
+	} else {
+		gconf_path = NULL;
+		g_warning ("Could not figure out gconf-path from dummy-key %s", dummy_key);
+		priv->settings = settings_new ();
+	}
+
+	g_free (dummy_key);
+
 	if (!priv->stuff->devinfo.name) {
 		GList *ptr, *devices = get_available_devices();
 		ptr = devices;
diff --git a/src/settings-dialog.c b/src/settings-dialog.c
index d24e5bd..117e1e2 100644
--- a/src/settings-dialog.c
+++ b/src/settings-dialog.c
@@ -56,92 +56,80 @@ settings_dialog_class_init (SettingsDialogClass *klass)
 							 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
 }
 
-/* Handle preference dialog response event
- */
-static void
-pref_response_cb (GtkDialog *dialog, gint id, gpointer data)
-{
-#if 0
-    NetspeedApplet *applet = data;
-  
-    if(id == GTK_RESPONSE_HELP){
-        display_help (GTK_WIDGET (dialog), "netspeed_applet-settings");
-	return;
-    }
-    panel_applet_gconf_set_string(PANEL_APPLET(applet->applet), "device", applet->devinfo.name, NULL);
-    panel_applet_gconf_set_bool(PANEL_APPLET(applet->applet), "show_sum", applet->show_sum, NULL);
-    panel_applet_gconf_set_bool(PANEL_APPLET(applet->applet), "show_bits", applet->show_bits, NULL);
-    panel_applet_gconf_set_bool(PANEL_APPLET(applet->applet), "change_icon", applet->change_icon, NULL);
-    panel_applet_gconf_set_bool(PANEL_APPLET(applet->applet), "auto_change_device", applet->auto_change_device, NULL);
-    panel_applet_gconf_set_bool(PANEL_APPLET(applet->applet), "have_settings", TRUE, NULL);
-
-    gtk_widget_destroy(GTK_WIDGET(applet->settings));
-    applet->settings = NULL;
-#endif
-}
-
-#if 0
 /* this basically just retrieves the new devicestring 
  * and then calls applet_device_change() and change_icons()
  */
 static void
-device_change_cb(GtkComboBox *combo, NetspeedApplet *applet)
+device_change_cb(GtkComboBox *combo, gpointer user_data)
 {
-	GList *devices;
-	int i, active;
-
-	g_assert(combo);
-	devices = g_object_get_data(G_OBJECT(combo), "devices");
-	active = gtk_combo_box_get_active(combo);
-	g_assert(active > -1);
-
-	if (0 == active) {
-		if (applet->auto_change_device)
-			return;
-		applet->auto_change_device = TRUE;
-	} else {
-		applet->auto_change_device = FALSE;
-		for (i = 1; i < active; i++) {
-			devices = g_list_next(devices);
-		}
-		if (g_str_equal(devices->data, applet->devinfo.name))
-			return;
-		free_device_info(&applet->devinfo);
-		get_device_info(devices->data, &applet->devinfo);
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	char *device;
+	gboolean auto_change_device;
+
+	SettingsDialogPrivate *priv = SETTINGS_DIALOG (user_data)->priv;
+
+	model = gtk_combo_box_get_model (combo);
+	if (gtk_combo_box_get_active_iter (combo, &iter)) {
+		gtk_tree_model_get (model,
+						&iter,
+						0, &device,
+						1, &auto_change_device,
+						-1);
+		g_object_set (priv->settings,
+						"default-route",
+						auto_change_device,
+						auto_change_device ? NULL : "device",
+						device,
+						NULL);
 	}
 
-	applet->device_has_changed = TRUE;
-	update_applet(applet);
+	//applet->device_has_changed = TRUE;
+	//update_applet(applet);
 }
 
 
 /* Called when the showsum checkbutton is toggled...
  */
 static void
-showsum_change_cb(GtkToggleButton *togglebutton, NetspeedApplet *applet)
+showsum_change_cb(GtkToggleButton *togglebutton, gpointer user_data)
 {
-	applet->show_sum = gtk_toggle_button_get_active(togglebutton);
-	applet_change_size_or_orient(applet->applet, -1, (gpointer)applet);
-	change_icons(applet);
+	SettingsDialogPrivate *priv = SETTINGS_DIALOG (user_data)->priv;
+
+	g_object_set (priv->settings,
+			"display-sum",
+			gtk_toggle_button_get_active (togglebutton),
+			NULL);
+	//applet_change_size_or_orient(applet->applet, -1, (gpointer)applet);
+	//change_icons(applet);
 }
 
 /* Called when the showbits checkbutton is toggled...
  */
 static void
-showbits_change_cb(GtkToggleButton *togglebutton, NetspeedApplet *applet)
+showbits_change_cb(GtkToggleButton *togglebutton, gpointer user_data)
 {
-	applet->show_bits = gtk_toggle_button_get_active(togglebutton);
+	SettingsDialogPrivate *priv = SETTINGS_DIALOG (user_data)->priv;
+
+	g_object_set (priv->settings,
+			"display-bits",
+			gtk_toggle_button_get_active (togglebutton),
+			NULL);
 }
 
 /* Called when the changeicon checkbutton is toggled...
  */
 static void
-changeicon_change_cb(GtkToggleButton *togglebutton, NetspeedApplet *applet)
+changeicon_change_cb(GtkToggleButton *togglebutton, gpointer user_data)
 {
-	applet->change_icon = gtk_toggle_button_get_active(togglebutton);
-	change_icons(applet);
+	SettingsDialogPrivate *priv = SETTINGS_DIALOG (user_data)->priv;
+
+	g_object_set (priv->settings,
+			"display-specific-icon",
+			gtk_toggle_button_get_active (togglebutton),
+			NULL);
+	//change_icons(applet);
 }
-#endif
 
 static void
 settings_dialog_init (SettingsDialog *self)
@@ -159,6 +147,7 @@ settings_dialog_init (SettingsDialog *self)
 	GtkSizeGroup *category_label_size_group;
 	GtkSizeGroup *category_units_size_group;
 	gchar *header_str;
+	GtkCellRenderer *renderer;
 
 	priv = SETTINGS_DIALOG_GET_PRIVATE (self);
 	self->priv = priv;
@@ -215,10 +204,17 @@ settings_dialog_init (SettingsDialog *self)
 	gtk_size_group_add_widget(category_label_size_group, network_device_label);
 	gtk_box_pack_start(GTK_BOX (network_device_hbox), network_device_label, FALSE, FALSE, 0);
 	
-	priv->network_device_combo = gtk_combo_box_new_text();
+	priv->network_device_combo = gtk_combo_box_new();
 	gtk_label_set_mnemonic_widget(GTK_LABEL(network_device_label), priv->network_device_combo);
 	gtk_box_pack_start (GTK_BOX (network_device_hbox), priv->network_device_combo, TRUE, TRUE, 0);
 
+	renderer = gtk_cell_renderer_text_new ();
+	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (priv->network_device_combo), renderer, TRUE);
+	gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (priv->network_device_combo),
+								renderer,
+								"text",
+								0);
+
 	priv->show_sum_checkbutton = gtk_check_button_new_with_mnemonic(_("Show _sum instead of in & out"));
 	gtk_box_pack_start(GTK_BOX(controls_vbox), priv->show_sum_checkbutton, FALSE, FALSE, 0);
 	
@@ -228,23 +224,6 @@ settings_dialog_init (SettingsDialog *self)
 	priv->change_icon_checkbutton = gtk_check_button_new_with_mnemonic(_("Change _icon according to the selected device"));
 	gtk_box_pack_start(GTK_BOX(controls_vbox), priv->change_icon_checkbutton, FALSE, FALSE, 0);
 
-#if 0
-	g_signal_connect(G_OBJECT (priv->network_device_combo), "changed",
-			 G_CALLBACK(device_change_cb), (gpointer)applet);
-
-	g_signal_connect(G_OBJECT (show_sum_checkbutton), "toggled",
-			 G_CALLBACK(showsum_change_cb), (gpointer)applet);
-
-	g_signal_connect(G_OBJECT (show_bits_checkbutton), "toggled",
-			 G_CALLBACK(showbits_change_cb), (gpointer)applet);
-
-	g_signal_connect(G_OBJECT (change_icon_checkbutton), "toggled",
-			 G_CALLBACK(changeicon_change_cb), (gpointer)applet);
-
-	g_signal_connect(G_OBJECT (priv->settings), "response",
-			 G_CALLBACK(pref_response_cb), (gpointer)applet);
-#endif
-
 	gtk_container_add(GTK_CONTAINER (GTK_DIALOG (self)->vbox), vbox);
 }
 
@@ -255,33 +234,50 @@ settings_dialog_constructed (GObject *object)
 	gboolean show_sum, show_bits, change_icon, auto_change_device;
 	char *device;
 	GList *ptr, *devices;
-	int i, active = -1;
+	GtkListStore *model;
+	GtkTreeIter iter;
 
 	g_object_get (priv->settings,
 				"device", &device,
-				"show-sum", &show_sum,
-				"show-bits", &show_bits,
-				"change-icon", &change_icon,
-				"auto-change-device", &auto_change_device,
+				"display-sum", &show_sum,
+				"display-bits", &show_bits,
+				"display-specific-icon", &change_icon,
+				"default-route", &auto_change_device,
 				NULL);
 
 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->show_sum_checkbutton), show_sum);
 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->show_bits_checkbutton), show_bits);
 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->change_icon_checkbutton), change_icon);
 
-	/* Default means device with default route set */
-	gtk_combo_box_append_text(GTK_COMBO_BOX(priv->network_device_combo), _("Default"));
+	model = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
+	gtk_combo_box_set_model (GTK_COMBO_BOX (priv->network_device_combo), GTK_TREE_MODEL (model));
 	ptr = devices = get_available_devices();
-	for (i = 1; ptr; ptr = g_list_next(ptr)) {
-		gtk_combo_box_append_text(GTK_COMBO_BOX(priv->network_device_combo), ptr->data);
-		if (g_str_equal(ptr->data, device)) active = i;
-		++i;
+	for (; ptr; ptr = g_list_next(ptr)) {
+		gtk_list_store_append (model, &iter);
+		gtk_list_store_set (model, &iter, 0, ptr->data, 1, FALSE, -1);
+		if (0 == g_strcmp0(ptr->data, device)) {
+			gtk_combo_box_set_active_iter (GTK_COMBO_BOX (priv->network_device_combo), &iter);
+		}
 	}
-	g_object_set_data_full(G_OBJECT(priv->network_device_combo), "devices", devices, (GDestroyNotify)free_devices_list);
-	if (active < 0 || auto_change_device) {
-		active = 0;
+	gtk_list_store_prepend (model, &iter);
+	/* Default means device with default route set */
+	gtk_list_store_set (model, &iter, 0, _("Default"), 1, TRUE, -1);
+	if (auto_change_device ||
+		gtk_combo_box_get_active (GTK_COMBO_BOX (priv->network_device_combo)) == -1) {
+		gtk_combo_box_set_active_iter (GTK_COMBO_BOX (priv->network_device_combo), &iter);
 	}
-	gtk_combo_box_set_active(GTK_COMBO_BOX(priv->network_device_combo), active);
+
+	g_signal_connect(G_OBJECT (priv->network_device_combo), "changed",
+			 G_CALLBACK(device_change_cb), object);
+
+	g_signal_connect(G_OBJECT (priv->show_sum_checkbutton), "toggled",
+			 G_CALLBACK(showsum_change_cb), object);
+
+	g_signal_connect(G_OBJECT (priv->show_bits_checkbutton), "toggled",
+			 G_CALLBACK(showbits_change_cb), object);
+
+	g_signal_connect(G_OBJECT (priv->change_icon_checkbutton), "toggled",
+			 G_CALLBACK(changeicon_change_cb), object);
 
 	if (G_OBJECT_CLASS (settings_dialog_parent_class)->constructed) {
 		G_OBJECT_CLASS (settings_dialog_parent_class)->constructed (object);
@@ -299,7 +295,7 @@ settings_dialog_set_property (GObject    *object,
 
 	switch (property_id) {
 		case PROP_SETTINGS:
-			priv->settings = g_value_get_object (value);
+			priv->settings = g_value_dup_object (value);
 			break;
 	}
 }
diff --git a/src/settings.c b/src/settings.c
index 1664319..fa7af03 100644
--- a/src/settings.c
+++ b/src/settings.c
@@ -21,35 +21,56 @@
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
+#include <gconf/gconf.h>
+#include <gconf/gconf-client.h>
 #include "settings.h"
 
 enum
 {
-	PROP_0,
+	PROP_0, /* dummy */
 	PROP_DEVICE,
-	PROP_SHOW_SUM,
-	PROP_SHOW_BITS,
-	PROP_CHANGE_ICON,
-	PROP_AUTO_CHANGE_DEVICE,
-	PROP_IN_COLOR,
-	PROP_OUT_COLOR,
-	PROP_UP_CMD,
-	PROP_DOWN_CMD
+	PROP_GCONF_PATH,
+	PROP_DEFAULT_ROUTE,
+	PROP_DISPLAY_SUM,
+	PROP_DISPLAY_BITS,
+	PROP_DISPLAY_SPECIFIC_ICON,
+	PROP_GRAPH_COLOR_IN,
+	PROP_GRAPH_COLOR_OUT,
+	PROP_IFUP_CMD,
+	PROP_IFDOWN_CMD
 };
 
 struct _SettingsPrivate
 {
 	char *device;
+	char *gconf_path;
+	gboolean follow_default_route;
+	struct {
+		gboolean sum;
+		gboolean bits;
+		gboolean specific_icon;
+	} display;
+	struct {
+		char* in;
+		char* out;
+	} graph_colors;
+	struct {
+		char *ifup;
+		char *ifdown;
+	} commands;
 };
 
 #define SETTINGS_GET_PRIVATE(o) \
 (G_TYPE_INSTANCE_GET_PRIVATE ((o), SETTINGS_TYPE, SettingsPrivate))
 
-static void settings_class_init (SettingsClass *klass);
-static void settings_init       (Settings *self);
-static void settings_finalize   (GObject *object);
-static void settings_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
-static void settings_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
+static void  settings_class_init (SettingsClass *klass);
+static void  settings_init       (Settings *self);
+static void  settings_finalize   (GObject *object);
+static void  settings_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
+static void  settings_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
+static void  settings_store_property (Settings *settings, int property_id, const GValue *value);
+static void  settings_load_all       (Settings *settings);
+static char* settings_gconf_key_from_property_id (Settings *settings, int property_id);
 
 G_DEFINE_TYPE (Settings, settings, G_TYPE_OBJECT);
 
@@ -66,10 +87,64 @@ settings_class_init (SettingsClass *klass)
 
 	g_object_class_install_property (object_class, PROP_DEVICE,
 		g_param_spec_string ("device",
-							 "Device",
-							 "The device that is monitored.",
-							 "lo",
-							 G_PARAM_READWRITE));
+							"Device",
+							"The device that is monitored.",
+							"lo",
+							G_PARAM_READWRITE));
+	g_object_class_install_property (object_class, PROP_GCONF_PATH,
+		g_param_spec_string ("gconf-path",
+							"GConf path",
+							"The applet instance' gconf path.",
+							NULL,
+							G_PARAM_READWRITE));
+	g_object_class_install_property (object_class, PROP_DEFAULT_ROUTE,
+		g_param_spec_boolean ("default-route",
+							"Default route",
+							"Track the device which has the default route set.",
+							TRUE,
+							G_PARAM_READWRITE));
+	g_object_class_install_property (object_class, PROP_DISPLAY_SUM,
+		g_param_spec_boolean ("display-sum",
+							"Display sum",
+							"Display the sum of incoming and outgoing traffic, instead of both individually.",
+							TRUE,
+							G_PARAM_READWRITE));
+	g_object_class_install_property (object_class, PROP_DISPLAY_BITS,
+		g_param_spec_boolean ("display-bits",
+							"Display Bits",
+							"Display traffic in bits instead of bytes.",
+							FALSE,
+							G_PARAM_READWRITE));
+	g_object_class_install_property (object_class, PROP_DISPLAY_SPECIFIC_ICON,
+		g_param_spec_boolean ("display-specific-icon",
+							"Display specific icon",
+							"Display a device specific icon.",
+							TRUE,
+							G_PARAM_READWRITE));
+	g_object_class_install_property (object_class, PROP_GRAPH_COLOR_IN,
+		g_param_spec_string ("graph-color-in",
+							"Graph color in",
+							"GdkColor for incoming traffic graph.",
+							"#00FF00",
+							G_PARAM_READWRITE));
+	g_object_class_install_property (object_class, PROP_GRAPH_COLOR_OUT,
+		g_param_spec_string ("graph-color-out",
+							"Graph color out",
+							"GdkColor for outgoing traffic graph.",
+							"#FF0000",
+							G_PARAM_READWRITE));
+	g_object_class_install_property (object_class, PROP_IFUP_CMD,
+		g_param_spec_string ("ifup-command",
+							"Ifup Command",
+							"Command to bring the specified device up.",
+							"/sbin/ifup",
+							G_PARAM_READWRITE));
+	g_object_class_install_property (object_class, PROP_IFDOWN_CMD,
+		g_param_spec_string ("ifdown-command",
+							"Ifdown Command",
+							"Command to bring the specified device down.",
+							"/sbin/ifdown",
+							G_PARAM_READWRITE));
 }
 
 static void
@@ -79,6 +154,15 @@ settings_init (Settings *self)
 	self->priv = priv;
 
 	priv->device = g_strdup ("lo");
+	priv->gconf_path = NULL;
+	priv->follow_default_route = TRUE;
+	priv->display.sum = FALSE;
+	priv->display.bits = FALSE;
+	priv->display.specific_icon = TRUE;
+	priv->graph_colors.in = g_strdup ("#00FF00");
+	priv->graph_colors.out = g_strdup ("#FF0000");
+	priv->commands.ifup = g_strdup ("/sbin/ifup");
+	priv->commands.ifdown = g_strdup ("/sbin/ifdown");
 }
 
 static void
@@ -94,6 +178,47 @@ settings_set_property (GObject       *object,
 			g_free (priv->device);
 			priv->device = g_value_dup_string (value);
 			break;
+		case PROP_GCONF_PATH:
+			g_free (priv->gconf_path);
+			priv->gconf_path = g_value_dup_string (value);
+			settings_load_all (SETTINGS (object));
+			return;
+		case PROP_DEFAULT_ROUTE:
+			priv->follow_default_route = g_value_get_boolean (value);
+			break;
+		case PROP_DISPLAY_SUM:
+			priv->display.sum = g_value_get_boolean (value);
+			break;
+		case PROP_DISPLAY_BITS:
+			priv->display.bits = g_value_get_boolean (value);
+			break;
+		case PROP_DISPLAY_SPECIFIC_ICON:
+			priv->display.specific_icon = g_value_get_boolean (value);
+			break;
+		case PROP_GRAPH_COLOR_IN:
+			g_free (priv->graph_colors.in);
+			priv->graph_colors.in = g_value_dup_string (value);
+			break;
+		case PROP_GRAPH_COLOR_OUT:
+			g_free (priv->graph_colors.out);
+			priv->graph_colors.out = g_value_dup_string (value);
+			break;
+		case PROP_IFUP_CMD:
+			g_free (priv->commands.ifup);
+			priv->commands.ifup = g_value_dup_string (value);
+			break;
+		case PROP_IFDOWN_CMD:
+			g_free (priv->commands.ifdown);
+			priv->commands.ifdown = g_value_dup_string (value);
+			break;
+		default:
+			return;
+	}
+	g_object_notify (object, g_param_spec_get_name (pspec));
+	if (priv->gconf_path) {
+		settings_store_property (SETTINGS (object),
+								property_id,
+								value);
 	}
 }
 
@@ -109,15 +234,173 @@ settings_get_property (GObject       *object,
 		case PROP_DEVICE:
 			g_value_set_string (value, priv->device);
 			break;
+		case PROP_GCONF_PATH:
+			g_value_set_string (value, priv->gconf_path);
+			break;
+		case PROP_DEFAULT_ROUTE:
+			g_value_set_boolean (value, priv->follow_default_route);
+			break;
+		case PROP_DISPLAY_SUM:
+			g_value_set_boolean (value, priv->display.sum);
+			break;
+		case PROP_DISPLAY_BITS:
+			g_value_set_boolean (value, priv->display.bits);
+			break;
+		case PROP_DISPLAY_SPECIFIC_ICON:
+			g_value_set_boolean (value, priv->display.specific_icon);
+			break;
+		case PROP_GRAPH_COLOR_IN:
+			g_value_set_string (value, priv->graph_colors.in);
+			break;
+		case PROP_GRAPH_COLOR_OUT:
+			g_value_set_string (value, priv->graph_colors.out);
+			break;
+		case PROP_IFUP_CMD:
+			g_value_set_string (value, priv->commands.ifup);
+			break;
+		case PROP_IFDOWN_CMD:
+			g_value_set_string (value, priv->commands.ifdown);
+			break;
 	}
 }
 
+static char*
+settings_gconf_key_from_property_id (Settings *settings, int property_id)
+{
+	SettingsPrivate *priv = settings->priv;
+	char *gconf_path = priv->gconf_path;
+
+	g_return_val_if_fail (gconf_path != NULL, NULL);
+
+	switch (property_id) {
+		case PROP_DEVICE:
+			return gconf_concat_dir_and_key (gconf_path, "device");
+		case PROP_DEFAULT_ROUTE:
+			return gconf_concat_dir_and_key (gconf_path, "auto_change_device");
+		case PROP_DISPLAY_SUM:
+			return gconf_concat_dir_and_key (gconf_path, "show_sum");
+		case PROP_DISPLAY_BITS:
+			return gconf_concat_dir_and_key (gconf_path, "show_bits");
+		case PROP_DISPLAY_SPECIFIC_ICON:
+			return gconf_concat_dir_and_key (gconf_path, "change_icon");
+		case PROP_GRAPH_COLOR_IN:
+			return gconf_concat_dir_and_key (gconf_path, "in_color");
+		case PROP_GRAPH_COLOR_OUT:
+			return gconf_concat_dir_and_key (gconf_path, "out_color");
+		case PROP_IFUP_CMD:
+			return gconf_concat_dir_and_key (gconf_path, "up_command");
+		case PROP_IFDOWN_CMD:
+			return gconf_concat_dir_and_key (gconf_path, "down_command");
+		case PROP_0:
+		case PROP_GCONF_PATH:
+			return NULL;
+		default:
+			g_warning ("No property with id %d", property_id);
+			return NULL;
+	}
+}
+
+static void
+settings_store_property (Settings *settings, int property_id, const GValue *value)
+{
+	SettingsPrivate *priv = settings->priv;
+	GConfClient *client;
+	GError *error = NULL;
+	char *key;
+
+	g_return_if_fail (priv->gconf_path != NULL);
+
+	client = gconf_client_get_default();
+	g_return_if_fail (client != NULL);
+
+	key = settings_gconf_key_from_property_id (settings, property_id);
+	g_return_if_fail (key != NULL);
+
+	if (G_VALUE_HOLDS_STRING (value)) {
+		gconf_client_set_string (client, key, g_value_get_string (value), &error);
+	} else
+	if (G_VALUE_HOLDS_BOOLEAN (value)) {
+		gconf_client_set_bool (client, key, g_value_get_boolean (value), &error);
+	} else {
+		g_warning ("Don't know how to convert property %d", property_id);
+	}
+	if (error) {
+		char* contents = g_strdup_value_contents (value);
+		g_warning ("Could not store value %s in key %s: %s", contents, key, error->message);
+		g_free (contents);
+		g_clear_error (&error);
+	}
+}
+
+static void
+settings_load_all (Settings *settings)
+{
+	SettingsPrivate *priv = settings->priv;
+	SettingsClass* class;
+	GConfClient *client;
+	GParamSpec** specs;
+	int i, n_specs;
+
+	if (!priv->gconf_path)
+		return;
+
+	client = gconf_client_get_default();
+	g_return_if_fail (client != NULL);
+
+	g_object_freeze_notify (G_OBJECT (settings));
+
+	class = SETTINGS_GET_CLASS (settings);
+	specs = g_object_class_list_properties (G_OBJECT_CLASS (class), &n_specs);
+	for (i = 0; i < n_specs; i++) {
+		GConfValue *value;
+		GError *error = NULL;
+		char *key;
+		const char *property_name;
+
+		key = settings_gconf_key_from_property_id (settings, i + 1);
+		if (!key) {
+			continue;
+		}
+		value = gconf_client_get (client, key, &error);
+		if (error) {
+			g_warning ("Could not get value for key %s: %s", key, error->message);
+			g_clear_error (&error);
+		}
+		property_name = g_param_spec_get_name (specs[i]);
+		/* Would be nice if there was some way to convert gconf-values to gvalues *sigh* */
+		if (value) {
+			switch (value->type) {
+				case GCONF_VALUE_STRING:
+					g_object_set (G_OBJECT (settings),
+								property_name,
+								gconf_value_get_string (value),
+								NULL);
+					break;
+				case GCONF_VALUE_BOOL:
+					g_object_set (G_OBJECT (settings),
+								property_name,
+								gconf_value_get_bool (value),
+								NULL);
+					break;
+				default:
+					g_warning ("Don't know how to convert property %s", property_name);
+			}
+		} /* Otherwise fall-back to hard-coded default */
+	}
+	g_free (specs);
+	g_object_thaw_notify (G_OBJECT (settings));
+}
+
 static void
 settings_finalize (GObject *object)
 {
 	SettingsPrivate *priv = SETTINGS (object)->priv;
 
 	g_free (priv->device);
+	g_free (priv->graph_colors.in);
+	g_free (priv->graph_colors.out);
+	g_free (priv->commands.ifup);
+	g_free (priv->commands.ifdown);
 
 	G_OBJECT_CLASS (settings_parent_class)->finalize (object);
 }
@@ -126,3 +409,10 @@ Settings* settings_new (void)
 {
 	return g_object_new (SETTINGS_TYPE, NULL);
 }
+
+Settings* settings_new_with_gconf_path (const char *gconf_path)
+{
+	return g_object_new (SETTINGS_TYPE,
+						"gconf-path", gconf_path,
+						NULL);
+}
diff --git a/src/settings.h b/src/settings.h
index 5649a15..c2227d5 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -51,6 +51,7 @@ struct _Settings
 GType     settings_get_type (void);
 
 Settings* settings_new (void);
+Settings* settings_new_with_gconf_path (const char *gconf_path);
 
 G_END_DECLS
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]