network-manager-applet r668 - in trunk: . src/connection-editor src/gconf-helpers



Author: dcbw
Date: Tue Apr 15 18:15:40 2008
New Revision: 668
URL: http://svn.gnome.org/viewvc/network-manager-applet?rev=668&view=rev

Log:
2008-04-15  Dan Williams  <dcbw redhat com>

	* src/connection-editor/page-ip4-address.c
	  src/connection-editor/page-ip4-address.h
	  src/connection-editor/ce-page-ip4-address.glade
	  src/connection-editor/Makefile.am
		- remove the source and glade files, everything IPv4 in one pane for now

	* src/connection-editor/nm-connection-editor.c
		- (nm_connection_editor_set_connection): remove usage of old ip4_address
			page
		- (connection_editor_update_connection): fill certs so that the connection
			has a chance of getting validated

	* src/gconf-helpers/gconf-helpers.c
	  src/gconf-helpers/gconf-helpers.h
		- (nm_gconf_get_ip4_addresses_helper, nm_gconf_set_ip4_addresses_helper):
			implement

	* src/connection-editor/ce-page-ip4.glade
		- Add IPv4 address bits; change DNS and search to entries

	* src/connection-editor/page-ip4.c
		- Fix up to work with new IPv4 page UI bits



Removed:
   trunk/src/connection-editor/ce-page-ip4-address.glade
   trunk/src/connection-editor/page-ip4-address.c
   trunk/src/connection-editor/page-ip4-address.h
Modified:
   trunk/ChangeLog
   trunk/src/connection-editor/Makefile.am
   trunk/src/connection-editor/ce-page-ip4.glade
   trunk/src/connection-editor/nm-connection-editor.c
   trunk/src/connection-editor/page-ip4.c
   trunk/src/gconf-helpers/gconf-helpers.c
   trunk/src/gconf-helpers/gconf-helpers.h

Modified: trunk/src/connection-editor/Makefile.am
==============================================================================
--- trunk/src/connection-editor/Makefile.am	(original)
+++ trunk/src/connection-editor/Makefile.am	Tue Apr 15 18:15:40 2008
@@ -36,8 +36,6 @@
 	page-wireless-security.c \
 	page-ip4.h \
 	page-ip4.c \
-	page-ip4-address.h \
-	page-ip4-address.c \
 	page-dsl.h \
 	page-dsl.c \
 	page-mobile.h \
@@ -56,7 +54,6 @@
 	ce-page-wireless.glade \
 	ce-page-wireless-security.glade \
 	ce-page-ip4.glade \
-	ce-page-ip4-address.glade \
 	ce-page-dsl.glade \
 	ce-page-mobile.glade
 

Modified: trunk/src/connection-editor/ce-page-ip4.glade
==============================================================================
--- trunk/src/connection-editor/ce-page-ip4.glade	(original)
+++ trunk/src/connection-editor/ce-page-ip4.glade	Tue Apr 15 18:15:40 2008
@@ -23,7 +23,7 @@
       <property name="border_width">12</property>
       <property name="visible">True</property>
       <property name="homogeneous">False</property>
-      <property name="spacing">18</property>
+      <property name="spacing">16</property>
 
       <child>
 	<widget class="GtkHBox" id="hbox1">
@@ -76,12 +76,12 @@
 	<packing>
 	  <property name="padding">0</property>
 	  <property name="expand">False</property>
-	  <property name="fill">False</property>
+	  <property name="fill">True</property>
 	</packing>
       </child>
 
       <child>
-	<widget class="GtkVBox" id="ip4_dns_servers_box">
+	<widget class="GtkVBox" id="ip4_addresses_box">
 	  <property name="visible">True</property>
 	  <property name="homogeneous">False</property>
 	  <property name="spacing">6</property>
@@ -89,7 +89,7 @@
 	  <child>
 	    <widget class="GtkLabel" id="label37">
 	      <property name="visible">True</property>
-	      <property name="label" translatable="yes">&lt;b&gt;DNS Servers&lt;/b&gt;</property>
+	      <property name="label" translatable="yes">&lt;b&gt;Addresses&lt;/b&gt;</property>
 	      <property name="use_underline">False</property>
 	      <property name="use_markup">True</property>
 	      <property name="justify">GTK_JUSTIFY_LEFT</property>
@@ -124,48 +124,26 @@
 	      <property name="right_padding">0</property>
 
 	      <child>
-		<widget class="GtkTable" id="table7">
+		<widget class="GtkVBox" id="vbox4">
 		  <property name="visible">True</property>
-		  <property name="n_rows">2</property>
-		  <property name="n_columns">2</property>
 		  <property name="homogeneous">False</property>
-		  <property name="row_spacing">6</property>
-		  <property name="column_spacing">6</property>
-
-		  <child>
-		    <widget class="GtkEntry" id="ip4_new_dns_server">
-		      <property name="visible">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="editable">True</property>
-		      <property name="visibility">True</property>
-		      <property name="max_length">0</property>
-		      <property name="text" translatable="yes"></property>
-		      <property name="has_frame">True</property>
-		      <property name="activates_default">False</property>
-		    </widget>
-		    <packing>
-		      <property name="left_attach">0</property>
-		      <property name="right_attach">1</property>
-		      <property name="top_attach">0</property>
-		      <property name="bottom_attach">1</property>
-		      <property name="y_options"></property>
-		    </packing>
-		  </child>
+		  <property name="spacing">0</property>
 
 		  <child>
 		    <widget class="GtkScrolledWindow" id="scrolledwindow1">
 		      <property name="visible">True</property>
 		      <property name="can_focus">True</property>
-		      <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+		      <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
 		      <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
 		      <property name="shadow_type">GTK_SHADOW_IN</property>
 		      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
 
 		      <child>
-			<widget class="GtkTreeView" id="ip4_dns_servers">
+			<widget class="GtkTreeView" id="ip4_addresses">
+			  <property name="height_request">100</property>
 			  <property name="visible">True</property>
 			  <property name="can_focus">True</property>
-			  <property name="headers_visible">False</property>
+			  <property name="headers_visible">True</property>
 			  <property name="rules_hint">True</property>
 			  <property name="reorderable">False</property>
 			  <property name="enable_search">True</property>
@@ -176,23 +154,22 @@
 		      </child>
 		    </widget>
 		    <packing>
-		      <property name="left_attach">0</property>
-		      <property name="right_attach">1</property>
-		      <property name="top_attach">1</property>
-		      <property name="bottom_attach">2</property>
-		      <property name="x_options">fill</property>
+		      <property name="padding">0</property>
+		      <property name="expand">True</property>
+		      <property name="fill">True</property>
 		    </packing>
 		  </child>
 
 		  <child>
-		    <widget class="GtkVButtonBox" id="vbuttonbox2">
+		    <widget class="GtkHButtonBox" id="hbuttonbox1">
 		      <property name="visible">True</property>
 		      <property name="layout_style">GTK_BUTTONBOX_START</property>
 		      <property name="spacing">6</property>
 
 		      <child>
-			<widget class="GtkButton" id="ip4_add_dns_server">
+			<widget class="GtkButton" id="ip4_addr_add_button">
 			  <property name="visible">True</property>
+			  <property name="can_default">True</property>
 			  <property name="can_focus">True</property>
 			  <property name="label">gtk-add</property>
 			  <property name="use_stock">True</property>
@@ -202,8 +179,9 @@
 		      </child>
 
 		      <child>
-			<widget class="GtkButton" id="ip4_delete_dns_server">
+			<widget class="GtkButton" id="ip4_addr_delete_button">
 			  <property name="visible">True</property>
+			  <property name="can_default">True</property>
 			  <property name="can_focus">True</property>
 			  <property name="label">gtk-delete</property>
 			  <property name="use_stock">True</property>
@@ -213,12 +191,9 @@
 		      </child>
 		    </widget>
 		    <packing>
-		      <property name="left_attach">1</property>
-		      <property name="right_attach">2</property>
-		      <property name="top_attach">0</property>
-		      <property name="bottom_attach">2</property>
-		      <property name="x_options">fill</property>
-		      <property name="y_options">fill</property>
+		      <property name="padding">6</property>
+		      <property name="expand">False</property>
+		      <property name="fill">True</property>
 		    </packing>
 		  </child>
 		</widget>
@@ -239,17 +214,21 @@
       </child>
 
       <child>
-	<widget class="GtkVBox" id="vbox3">
+	<widget class="GtkTable" id="table8">
+	  <property name="border_width">6</property>
 	  <property name="visible">True</property>
+	  <property name="n_rows">4</property>
+	  <property name="n_columns">2</property>
 	  <property name="homogeneous">False</property>
-	  <property name="spacing">6</property>
+	  <property name="row_spacing">6</property>
+	  <property name="column_spacing">6</property>
 
 	  <child>
-	    <widget class="GtkLabel" id="ip4_search_domains_box">
+	    <widget class="GtkLabel" id="label39">
 	      <property name="visible">True</property>
-	      <property name="label" translatable="yes">&lt;b&gt;Search Domains&lt;/b&gt;</property>
+	      <property name="label" translatable="yes">DNS Servers:</property>
 	      <property name="use_underline">False</property>
-	      <property name="use_markup">True</property>
+	      <property name="use_markup">False</property>
 	      <property name="justify">GTK_JUSTIFY_LEFT</property>
 	      <property name="wrap">False</property>
 	      <property name="selectable">False</property>
@@ -263,135 +242,142 @@
 	      <property name="angle">0</property>
 	    </widget>
 	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
+	      <property name="left_attach">0</property>
+	      <property name="right_attach">1</property>
+	      <property name="top_attach">0</property>
+	      <property name="bottom_attach">1</property>
+	      <property name="x_options">fill</property>
+	      <property name="y_options"></property>
 	    </packing>
 	  </child>
 
 	  <child>
-	    <widget class="GtkAlignment" id="alignment3">
+	    <widget class="GtkEntry" id="ip4_dns_servers_entry">
 	      <property name="visible">True</property>
-	      <property name="xalign">0.5</property>
-	      <property name="yalign">0.5</property>
-	      <property name="xscale">1</property>
-	      <property name="yscale">1</property>
-	      <property name="top_padding">0</property>
-	      <property name="bottom_padding">0</property>
-	      <property name="left_padding">12</property>
-	      <property name="right_padding">0</property>
-
-	      <child>
-		<widget class="GtkTable" id="table8">
-		  <property name="visible">True</property>
-		  <property name="n_rows">2</property>
-		  <property name="n_columns">2</property>
-		  <property name="homogeneous">False</property>
-		  <property name="row_spacing">6</property>
-		  <property name="column_spacing">6</property>
-
-		  <child>
-		    <widget class="GtkEntry" id="ip4_new_search_domain">
-		      <property name="visible">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="editable">True</property>
-		      <property name="visibility">True</property>
-		      <property name="max_length">0</property>
-		      <property name="text" translatable="yes"></property>
-		      <property name="has_frame">True</property>
-		      <property name="activates_default">False</property>
-		    </widget>
-		    <packing>
-		      <property name="left_attach">0</property>
-		      <property name="right_attach">1</property>
-		      <property name="top_attach">0</property>
-		      <property name="bottom_attach">1</property>
-		      <property name="y_options"></property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkScrolledWindow" id="scrolledwindow2">
-		      <property name="visible">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-		      <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-		      <property name="shadow_type">GTK_SHADOW_IN</property>
-		      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+	      <property name="can_focus">True</property>
+	      <property name="editable">True</property>
+	      <property name="visibility">True</property>
+	      <property name="max_length">0</property>
+	      <property name="text" translatable="yes"></property>
+	      <property name="has_frame">True</property>
+	      <property name="activates_default">False</property>
+	    </widget>
+	    <packing>
+	      <property name="left_attach">1</property>
+	      <property name="right_attach">2</property>
+	      <property name="top_attach">0</property>
+	      <property name="bottom_attach">1</property>
+	      <property name="y_options"></property>
+	    </packing>
+	  </child>
 
-		      <child>
-			<widget class="GtkTreeView" id="ip4_search_domains">
-			  <property name="visible">True</property>
-			  <property name="can_focus">True</property>
-			  <property name="headers_visible">False</property>
-			  <property name="rules_hint">True</property>
-			  <property name="reorderable">False</property>
-			  <property name="enable_search">True</property>
-			  <property name="fixed_height_mode">False</property>
-			  <property name="hover_selection">False</property>
-			  <property name="hover_expand">False</property>
-			</widget>
-		      </child>
-		    </widget>
-		    <packing>
-		      <property name="left_attach">0</property>
-		      <property name="right_attach">1</property>
-		      <property name="top_attach">1</property>
-		      <property name="bottom_attach">2</property>
-		      <property name="x_options">fill</property>
-		    </packing>
-		  </child>
+	  <child>
+	    <widget class="GtkLabel" id="label40">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">Search Domains:</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">False</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="left_attach">0</property>
+	      <property name="right_attach">1</property>
+	      <property name="top_attach">2</property>
+	      <property name="bottom_attach">3</property>
+	      <property name="x_options">fill</property>
+	      <property name="y_options"></property>
+	    </packing>
+	  </child>
 
-		  <child>
-		    <widget class="GtkVButtonBox" id="vbuttonbox3">
-		      <property name="visible">True</property>
-		      <property name="layout_style">GTK_BUTTONBOX_START</property>
-		      <property name="spacing">6</property>
+	  <child>
+	    <widget class="GtkEntry" id="ip4_dns_searches_entry">
+	      <property name="visible">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="editable">True</property>
+	      <property name="visibility">True</property>
+	      <property name="max_length">0</property>
+	      <property name="text" translatable="yes"></property>
+	      <property name="has_frame">True</property>
+	      <property name="activates_default">False</property>
+	    </widget>
+	    <packing>
+	      <property name="left_attach">1</property>
+	      <property name="right_attach">2</property>
+	      <property name="top_attach">2</property>
+	      <property name="bottom_attach">3</property>
+	      <property name="y_options"></property>
+	    </packing>
+	  </child>
 
-		      <child>
-			<widget class="GtkButton" id="ip4_add_search_domain">
-			  <property name="visible">True</property>
-			  <property name="can_focus">True</property>
-			  <property name="label">gtk-add</property>
-			  <property name="use_stock">True</property>
-			  <property name="relief">GTK_RELIEF_NORMAL</property>
-			  <property name="focus_on_click">True</property>
-			</widget>
-		      </child>
+	  <child>
+	    <widget class="GtkLabel" id="ip4_dns_servers_label">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">&lt;span style=&quot;italic&quot;&gt;Example: 10.10.10.1, 10.10.10.2&lt;/span&gt;</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">True</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">False</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="left_attach">1</property>
+	      <property name="right_attach">2</property>
+	      <property name="top_attach">1</property>
+	      <property name="bottom_attach">2</property>
+	      <property name="x_options">fill</property>
+	      <property name="y_options"></property>
+	    </packing>
+	  </child>
 
-		      <child>
-			<widget class="GtkButton" id="ip4_delete_search_domain">
-			  <property name="visible">True</property>
-			  <property name="can_focus">True</property>
-			  <property name="label">gtk-delete</property>
-			  <property name="use_stock">True</property>
-			  <property name="relief">GTK_RELIEF_NORMAL</property>
-			  <property name="focus_on_click">True</property>
-			</widget>
-		      </child>
-		    </widget>
-		    <packing>
-		      <property name="left_attach">1</property>
-		      <property name="right_attach">2</property>
-		      <property name="top_attach">0</property>
-		      <property name="bottom_attach">2</property>
-		      <property name="x_options">fill</property>
-		      <property name="y_options">fill</property>
-		    </packing>
-		  </child>
-		</widget>
-	      </child>
+	  <child>
+	    <widget class="GtkLabel" id="label44">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">&lt;span style=&quot;italic&quot;&gt;Example: lab.gnome.org, gnome.org&lt;/span&gt;</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">True</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">False</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
 	    </widget>
 	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
+	      <property name="left_attach">1</property>
+	      <property name="right_attach">2</property>
+	      <property name="top_attach">3</property>
+	      <property name="bottom_attach">4</property>
+	      <property name="x_options">fill</property>
+	      <property name="y_options"></property>
 	    </packing>
 	  </child>
 	</widget>
 	<packing>
 	  <property name="padding">0</property>
-	  <property name="expand">True</property>
+	  <property name="expand">False</property>
 	  <property name="fill">True</property>
 	</packing>
       </child>

Modified: trunk/src/connection-editor/nm-connection-editor.c
==============================================================================
--- trunk/src/connection-editor/nm-connection-editor.c	(original)
+++ trunk/src/connection-editor/nm-connection-editor.c	Tue Apr 15 18:15:40 2008
@@ -55,7 +55,6 @@
 #include "page-wireless.h"
 #include "page-wireless-security.h"
 #include "page-ip4.h"
-#include "page-ip4-address.h"
 #include "page-dsl.h"
 #include "page-mobile.h"
 
@@ -379,7 +378,6 @@
 	if (!strcmp (s_con->type, NM_SETTING_WIRED_SETTING_NAME)) {
 		add_page (editor, CE_PAGE (ce_page_wired_new (editor->connection)));
 		add_page (editor, CE_PAGE (ce_page_wired_security_new (editor->connection)));
-		add_page (editor, CE_PAGE (ce_page_ip4_address_new (editor->connection)));
 		add_page (editor, CE_PAGE (ce_page_ip4_new (editor->connection)));
 	} else if (!strcmp (s_con->type, NM_SETTING_WIRELESS_SETTING_NAME)) {
 		CEPageWireless *wireless_page;
@@ -391,10 +389,8 @@
 		wireless_security_page = ce_page_wireless_security_new (editor->connection, wireless_page);
 		add_page (editor, CE_PAGE (wireless_security_page));
 
-		add_page (editor, CE_PAGE (ce_page_ip4_address_new (editor->connection)));
 		add_page (editor, CE_PAGE (ce_page_ip4_new (editor->connection)));
 	} else if (!strcmp (s_con->type, NM_SETTING_VPN_SETTING_NAME)) {
-		add_page (editor, CE_PAGE (ce_page_ip4_address_new (editor->connection)));
 		add_page (editor, CE_PAGE (ce_page_ip4_new (editor->connection)));
 	} else if (!strcmp (s_con->type, NM_SETTING_PPPOE_SETTING_NAME)) {
 		add_page (editor, CE_PAGE (ce_page_dsl_new (editor->connection)));
@@ -439,10 +435,13 @@
 
 	g_slist_foreach (editor->pages, update_one_page, editor->connection);
 
+	utils_fill_connection_certs (editor->connection);
 	if (!nm_connection_verify (editor->connection)) {
+		utils_clear_filled_connection_certs (editor->connection);
 		g_warning ("%s: connection invalid after update; bug in the connection editor.", __func__);
 		return;
 	}
+	utils_clear_filled_connection_certs (editor->connection);
 
 	if (!editor->gconf_path) {
 		guint32 i = 0;

Modified: trunk/src/connection-editor/page-ip4.c
==============================================================================
--- trunk/src/connection-editor/page-ip4.c	(original)
+++ trunk/src/connection-editor/page-ip4.c	Tue Apr 15 18:15:40 2008
@@ -42,17 +42,16 @@
 
 	GtkComboBox *method;
 
+	/* Addresses */
+	GtkButton *addr_add;
+	GtkButton *addr_delete;
+	GtkTreeView *addr_list;
+
 	/* DNS servers */
-	GtkEntry *dns_new;
-	GtkButton *dns_add;
-	GtkButton *dns_remove;
-	GtkTreeView *dns_list;
+	GtkEntry *dns_servers;
 
 	/* Search domains */
-	GtkEntry *search_new;
-	GtkButton *search_add;
-	GtkButton *search_remove;
-	GtkTreeView *search_list;
+	GtkEntry *dns_searches;
 
 	gboolean disposed;
 } CEPageIP4Private;
@@ -61,6 +60,10 @@
 #define IP4_METHOD_AUTOIP 1
 #define IP4_METHOD_MANUAL 2
 
+#define COL_ADDRESS 0
+#define COL_NETMASK 1
+#define COL_GATEWAY 2
+
 static void
 ip4_private_init (CEPageIP4 *self)
 {
@@ -71,15 +74,12 @@
 
 	priv->method = GTK_COMBO_BOX (glade_xml_get_widget (xml, "ip4_method"));
 
-	priv->dns_new = GTK_ENTRY (glade_xml_get_widget (xml, "ip4_new_dns_server"));
-	priv->dns_add = GTK_BUTTON (glade_xml_get_widget (xml, "ip4_add_dns_server"));
-	priv->dns_remove = GTK_BUTTON (glade_xml_get_widget (xml, "ip4_delete_dns_server"));
-	priv->dns_list = GTK_TREE_VIEW (glade_xml_get_widget (xml, "ip4_dns_servers"));
-
-	priv->search_new = GTK_ENTRY (glade_xml_get_widget (xml, "ip4_new_search_domain"));
-	priv->search_add = GTK_BUTTON (glade_xml_get_widget (xml, "ip4_add_search_domain"));
-	priv->search_remove = GTK_BUTTON (glade_xml_get_widget (xml, "ip4_delete_search_domain"));
-	priv->search_list = GTK_TREE_VIEW (glade_xml_get_widget (xml, "ip4_search_domains"));
+	priv->addr_add = GTK_BUTTON (glade_xml_get_widget (xml, "ip4_addr_add_button"));
+	priv->addr_delete = GTK_BUTTON (glade_xml_get_widget (xml, "ip4_addr_delete_button"));
+	priv->addr_list = GTK_TREE_VIEW (glade_xml_get_widget (xml, "ip4_addresses"));
+
+	priv->dns_servers = GTK_ENTRY (glade_xml_get_widget (xml, "ip4_dns_servers_entry"));
+	priv->dns_searches = GTK_ENTRY (glade_xml_get_widget (xml, "ip4_dns_searches_entry"));
 }
 
 static void
@@ -114,6 +114,7 @@
 	GtkTreeIter model_iter;
 	GSList *iter;
 	int method = IP4_METHOD_DHCP;
+	GString *string = NULL;
 
 	/* Method */
 	if (setting->method) {
@@ -125,101 +126,170 @@
 	gtk_combo_box_set_active (priv->method, method);
 	g_signal_connect (priv->method, "changed", G_CALLBACK (method_changed), self);
 
+	/* Addresses */
+	store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+	for (iter = setting->addresses; iter; iter = g_slist_next (iter)) {
+		NMSettingIP4Address *addr = (NMSettingIP4Address *) iter->data;
+		struct in_addr tmp_addr;
+		gchar *ip_string;
+
+		if (!addr) {
+			g_warning ("%s: empty IP4 Address structure!", __func__);
+			continue;
+		}
+
+		gtk_list_store_append (store, &model_iter);
+
+		tmp_addr.s_addr = addr->address;
+		ip_string = inet_ntoa (tmp_addr);
+		gtk_list_store_set (store, &model_iter, COL_ADDRESS, g_strdup (ip_string), -1);
+
+		tmp_addr.s_addr = addr->netmask;
+		ip_string = inet_ntoa (tmp_addr);
+		gtk_list_store_set (store, &model_iter, COL_NETMASK, g_strdup (ip_string), -1);
+
+		tmp_addr.s_addr = addr->gateway;
+		ip_string = inet_ntoa (tmp_addr);
+		gtk_list_store_set (store, &model_iter, COL_GATEWAY, g_strdup (ip_string), -1);
+	}
+
+	gtk_tree_view_set_model (priv->addr_list, GTK_TREE_MODEL (store));
+	g_signal_connect (store, "row-inserted", G_CALLBACK (row_added), self);
+	g_signal_connect (store, "row-deleted", G_CALLBACK (row_removed), self);
+	g_object_unref (store);
+
 	/* DNS servers */
-	store = gtk_list_store_new (1, G_TYPE_STRING);
 	if (setting->dns) {
 		int i;
 
+		string = g_string_new ("");
 		for (i = 0; i < setting->dns->len; i++) {
 			struct in_addr tmp_addr;
-			gchar *ip_string;
+			char *ip_string;
 
-			tmp_addr.s_addr = g_array_index (setting->dns, guint, i);
-			ip_string = inet_ntoa (tmp_addr);
+			tmp_addr.s_addr = g_array_index (setting->dns, guint32, i);
+			if (!tmp_addr.s_addr)
+				continue;
 
-			gtk_list_store_append (store, &model_iter);
-			gtk_list_store_set (store, &model_iter, 0, g_strdup (ip_string), -1);
+			ip_string = inet_ntoa (tmp_addr);
+			if (string->len)
+				g_string_append (string, ", ");
+			g_string_append (string, ip_string);
 		}
-	}
 
-	gtk_tree_view_set_model (priv->dns_list, GTK_TREE_MODEL (store));
-	g_signal_connect (store, "row-inserted", G_CALLBACK (row_added), self);
-	g_signal_connect (store, "row-deleted", G_CALLBACK (row_removed), self);
-	g_object_unref (store);
-
-	/* Search domains */
-	store = gtk_list_store_new (1, G_TYPE_STRING);
-	for (iter = setting->dns_search; iter; iter = iter->next) {
-		gtk_list_store_append (store, &model_iter);
-		gtk_list_store_set (store, &model_iter, 0, iter->data, -1);
+		gtk_entry_set_text (priv->dns_servers, string->str);
+		g_string_free (string, TRUE);
 	}
 
-	gtk_tree_view_set_model (priv->search_list, GTK_TREE_MODEL (store));
-	g_signal_connect (store, "row-inserted", G_CALLBACK (row_added), self);
-	g_signal_connect (store, "row-deleted", G_CALLBACK (row_removed), self);
-	g_object_unref (store);
+	/* DNS searches */
+	string = g_string_new ("");
+	for (iter = setting->dns_search; iter; iter = g_slist_next (iter)) {
+		if (string->len)
+			g_string_append (string, ", ");
+		g_string_append (string, g_strdup (iter->data));
+	}
+	gtk_entry_set_text (priv->dns_searches, string->str);
+	g_string_free (string, TRUE);
 }
 
 static void
-dns_new_changed (GtkEditable *entry, gpointer user_data)
+dns_servers_changed (GtkEditable *entry, gpointer user_data)
 {
-	CEPageIP4Private *priv = CE_PAGE_IP4_GET_PRIVATE (user_data);
 	const char *text;
-	struct in_addr tmp_addr;
+	char **ips = NULL, **iter;
+	gboolean valid = TRUE;
 
 	text = gtk_entry_get_text (GTK_ENTRY (entry));
-	gtk_widget_set_sensitive (GTK_WIDGET (priv->dns_add),
-							  (text && strlen (text) > 0 && inet_aton (text, &tmp_addr) != 0));
-}
+	if (!text || !strlen (text))
+		goto out;
 
-static void
-dns_add_clicked (GtkButton *button, gpointer user_data)
-{
-	CEPageIP4Private *priv = CE_PAGE_IP4_GET_PRIVATE (user_data);
-	GtkListStore *store;
-	GtkTreeIter iter;
+	ips = g_strsplit (text, ",", 0);
+	for (iter = ips; *iter; iter++) {
+		struct in_addr tmp_addr;
+		
+		if (inet_aton (g_strstrip (*iter), &tmp_addr) == 0) {
+			valid = FALSE;
+			break;
+		}
+	}
 
-	store = GTK_LIST_STORE (gtk_tree_view_get_model (priv->dns_list));
-	gtk_list_store_append (store, &iter);
-	gtk_list_store_set (store, &iter, 0, g_strdup (gtk_entry_get_text (priv->dns_new)), -1);
-	gtk_entry_set_text (priv->dns_new, "");
+	if (ips)
+		g_strfreev (ips);
 
-	ce_page_changed (CE_PAGE (user_data));
+out:
+	/* FIXME: do something with 'valid' */
+	return;
 }
 
 static void
-search_new_changed (GtkEditable *entry, gpointer user_data)
+dns_searches_changed (GtkEditable *entry, gpointer user_data)
 {
-	CEPageIP4Private *priv = CE_PAGE_IP4_GET_PRIVATE (user_data);
 	const char *text;
+	char **searches = NULL, **iter;
+	gboolean valid = TRUE;
 
 	text = gtk_entry_get_text (GTK_ENTRY (entry));
-	gtk_widget_set_sensitive (GTK_WIDGET (priv->search_add), (text && strlen (text) > 0));
+	if (!text || !strlen (text))
+		goto out;
+
+	searches = g_strsplit (text, ",", 0);
+	for (iter = searches; *iter; iter++) {
+		/* Need at least one . in the search domain */
+		if (!strchr (g_strstrip (*iter), '.')) {
+			valid = FALSE;
+			break;
+		}
+	}
+
+	if (searches)
+		g_strfreev (searches);
+
+out:
+	/* FIXME: do something with 'valid' */
+	return;
 }
 
 static void
-search_add_clicked (GtkButton *button, gpointer user_data)
+addr_add_clicked (GtkButton *button, gpointer user_data)
 {
 	CEPageIP4Private *priv = CE_PAGE_IP4_GET_PRIVATE (user_data);
 	GtkListStore *store;
 	GtkTreeIter iter;
+	GtkTreeSelection *selection;
+	GtkTreeViewColumn *column;
+	GtkTreePath *path;
+	GList *cells;
 
-	store = GTK_LIST_STORE (gtk_tree_view_get_model (priv->search_list));
+	store = GTK_LIST_STORE (gtk_tree_view_get_model (priv->addr_list));
 	gtk_list_store_append (store, &iter);
-	gtk_list_store_set (store, &iter, 0, g_strdup (gtk_entry_get_text (priv->search_new)), -1);
-	gtk_entry_set_text (priv->search_new, "");
+	gtk_list_store_set (store, &iter, 0, g_strdup (""), -1);
 
-	ce_page_changed (CE_PAGE (user_data));
+	selection = gtk_tree_view_get_selection (priv->addr_list);
+	gtk_tree_selection_select_iter (selection, &iter);
+
+	path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter);
+	column = gtk_tree_view_get_column (priv->addr_list, COL_ADDRESS);
+
+	/* FIXME: using cells->data is pretty fragile but GTK apparently doesn't
+	 * have a way to get a cell renderer from a column based on path or iter
+	 * or whatever.
+	 */
+	cells = gtk_tree_view_column_get_cell_renderers (column);
+	gtk_tree_view_set_cursor_on_cell (priv->addr_list, path, column, cells->data, TRUE);
+
+	g_list_free (cells);
+	gtk_tree_path_free (path);
 }
 
 static void
-remove_clicked (GtkButton *button, gpointer user_data)
+addr_delete_clicked (GtkButton *button, gpointer user_data)
 {
 	GtkTreeView *treeview = GTK_TREE_VIEW (user_data);
 	GtkTreeSelection *selection;
 	GList *selected_rows;
 	GtkTreeModel *model = NULL;
 	GtkTreeIter iter;
+	int num_rows;
 
 	selection = gtk_tree_view_get_selection (treeview);
 	if (gtk_tree_selection_count_selected_rows (selection) != 1)
@@ -234,6 +304,12 @@
 
 	g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
 	g_list_free (selected_rows);
+
+	num_rows = gtk_tree_model_iter_n_children (model, NULL);
+	if (num_rows && gtk_tree_model_iter_nth_child (model, &iter, NULL, num_rows - 1)) {
+		selection = gtk_tree_view_get_selection (treeview);
+		gtk_tree_selection_select_iter (selection, &iter);
+	}
 }
 
 static void
@@ -249,6 +325,69 @@
 		gtk_widget_set_sensitive (button, FALSE);
 }
 
+static void
+cell_edited (GtkCellRendererText *cell,
+             const gchar *path_string,
+             const gchar *new_text,
+             gpointer user_data)
+{
+	GtkListStore *store = GTK_LIST_STORE (user_data);
+	GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
+	GtkTreeIter iter;
+	guint32 column = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (cell), "column"));
+
+	gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path);
+	gtk_list_store_set (store, &iter, column, new_text, -1);
+	gtk_tree_path_free (path);
+}
+
+static void
+ip_address_filter_cb (GtkEntry *   entry,
+                      const gchar *text,
+                      gint         length,
+                      gint *       position,
+                      gpointer     data)
+{
+	GtkEditable *editable = GTK_EDITABLE (entry);
+	int i, count = 0;
+	gchar *result = g_new (gchar, length);
+
+	for (i = 0; i < length; i++) {
+		if ((text[i] >= '0' && text[i] <= '9') || (text[i] == '.'))
+			result[count++] = text[i];
+	}
+
+	if (count > 0) {
+		g_signal_handlers_block_by_func (G_OBJECT (editable),
+		                                 G_CALLBACK (ip_address_filter_cb),
+		                                 data);
+		gtk_editable_insert_text (editable, result, count, position);
+		g_signal_handlers_unblock_by_func (G_OBJECT (editable),
+		                                   G_CALLBACK (ip_address_filter_cb),
+		                                   data);
+	}
+
+	g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text");
+	g_free (result);
+}
+
+static void
+cell_editing_started (GtkCellRenderer *cell,
+                      GtkCellEditable *editable,
+                      const gchar     *path,
+                      gpointer         data)
+{
+	if (!GTK_IS_ENTRY (editable)) {
+		g_warning ("%s: Unexpected cell editable type.", __func__);
+		return;
+	}
+
+	/* Set up the entry filter */
+	g_signal_connect (G_OBJECT (editable), "insert-text",
+	                  (GCallback) ip_address_filter_cb,
+	                  data);
+}
+
 CEPageIP4 *
 ce_page_ip4_new (NMConnection *connection)
 {
@@ -257,6 +396,10 @@
 	CEPage *parent;
 	NMSettingIP4Config *s_ip4;
 	GtkTreeSelection *selection;
+	gint offset;
+	GtkTreeViewColumn *column;
+	GtkCellRenderer *renderer;
+	GtkListStore *store;
 
 	self = CE_PAGE_IP4 (g_object_new (CE_TYPE_PAGE_IP4, NULL));
 	parent = CE_PAGE (self);
@@ -289,47 +432,87 @@
 
 	populate_ui (self);
 
-	gtk_tree_view_insert_column_with_attributes (priv->dns_list,
-	                                             -1, "", gtk_cell_renderer_text_new (),
-	                                             "text", 0,
-	                                             NULL);
-
-	gtk_tree_view_insert_column_with_attributes (priv->search_list,
-	                                             -1, "", gtk_cell_renderer_text_new (),
-	                                             "text", 0,
-	                                             NULL);
-
-	gtk_widget_set_sensitive (GTK_WIDGET (priv->dns_add), FALSE);
-	gtk_widget_set_sensitive (GTK_WIDGET (priv->dns_remove), FALSE);
-	gtk_widget_set_sensitive (GTK_WIDGET (priv->search_add), FALSE);
-	gtk_widget_set_sensitive (GTK_WIDGET (priv->search_remove), FALSE);
-
-	g_signal_connect (priv->dns_new, "changed", G_CALLBACK (dns_new_changed), self);
-	g_signal_connect (priv->dns_add, "clicked", G_CALLBACK (dns_add_clicked), self);
-	g_signal_connect (priv->dns_remove, "clicked", G_CALLBACK (remove_clicked), priv->dns_list);
-	selection = gtk_tree_view_get_selection (priv->dns_list);
-	g_signal_connect (selection, "changed", G_CALLBACK (list_selection_changed), priv->dns_remove);
-
-	g_signal_connect (priv->search_new, "changed", G_CALLBACK (search_new_changed), self);
-	g_signal_connect (priv->search_add, "clicked", G_CALLBACK (search_add_clicked), self);
-	g_signal_connect (priv->search_remove, "clicked", G_CALLBACK (remove_clicked), priv->search_list);
-	selection = gtk_tree_view_get_selection (priv->search_list);
-	g_signal_connect (selection, "changed", G_CALLBACK (list_selection_changed), priv->search_remove);
+	/* Address column */
+	store = GTK_LIST_STORE (gtk_tree_view_get_model (priv->addr_list));
+
+	/* IP Address column */
+	renderer = gtk_cell_renderer_text_new ();
+	g_object_set (renderer, "editable", TRUE, NULL);
+	g_signal_connect (renderer, "edited", G_CALLBACK (cell_edited), store);
+	g_object_set_data (G_OBJECT (renderer), "column", GUINT_TO_POINTER (COL_ADDRESS));
+	g_signal_connect (renderer, "editing-started", G_CALLBACK (cell_editing_started), store);
+
+	offset = gtk_tree_view_insert_column_with_attributes (priv->addr_list,
+	                                                      -1, _("Address"), renderer,
+	                                                      "text", COL_ADDRESS,
+	                                                      NULL);
+	column = gtk_tree_view_get_column (GTK_TREE_VIEW (priv->addr_list), offset - 1);
+	gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE);
+	gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE);
+
+	/* Netmask column */
+	renderer = gtk_cell_renderer_text_new ();
+	g_object_set (renderer, "editable", TRUE, NULL);
+	g_signal_connect (renderer, "edited", G_CALLBACK (cell_edited), store);
+	g_object_set_data (G_OBJECT (renderer), "column", GUINT_TO_POINTER (COL_NETMASK));
+	g_signal_connect (renderer, "editing-started", G_CALLBACK (cell_editing_started), store);
+
+	offset = gtk_tree_view_insert_column_with_attributes (priv->addr_list,
+	                                                      -1, _("Netmask"), renderer,
+	                                                      "text", COL_NETMASK,
+	                                                      NULL);
+	column = gtk_tree_view_get_column (GTK_TREE_VIEW (priv->addr_list), offset - 1);
+	gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE);
+	gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE);
+
+	/* Gateway column */
+	renderer = gtk_cell_renderer_text_new ();
+	g_object_set (renderer, "editable", TRUE, NULL);
+	g_signal_connect (renderer, "edited", G_CALLBACK (cell_edited), store);
+	g_object_set_data (G_OBJECT (renderer), "column", GUINT_TO_POINTER (COL_GATEWAY));
+	g_signal_connect (renderer, "editing-started", G_CALLBACK (cell_editing_started), store);
+
+	offset = gtk_tree_view_insert_column_with_attributes (priv->addr_list,
+	                                                      -1, _("Gateway"), renderer,
+	                                                      "text", COL_GATEWAY,
+	                                                      NULL);
+	column = gtk_tree_view_get_column (GTK_TREE_VIEW (priv->addr_list), offset - 1);
+	gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE);
+	gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE);
+
+	gtk_widget_set_sensitive (GTK_WIDGET (priv->addr_add), TRUE);
+	gtk_widget_set_sensitive (GTK_WIDGET (priv->addr_delete), FALSE);
+
+	g_signal_connect (priv->addr_add, "clicked", G_CALLBACK (addr_add_clicked), self);
+	g_signal_connect (priv->addr_delete, "clicked", G_CALLBACK (addr_delete_clicked), priv->addr_list);
+	selection = gtk_tree_view_get_selection (priv->addr_list);
+	g_signal_connect (selection, "changed", G_CALLBACK (list_selection_changed), priv->addr_delete);
+
+	g_signal_connect (priv->dns_servers, "changed", G_CALLBACK (dns_servers_changed), self);
+	g_signal_connect (priv->dns_searches, "changed", G_CALLBACK (dns_searches_changed), self);
 
 	return self;
 }
 
 static void
+free_one_addr (gpointer data)
+{
+	g_array_free ((GArray *) data, TRUE);
+}
+
+static void
 ui_to_setting (CEPageIP4 *self)
 {
 	CEPageIP4Private *priv = CE_PAGE_IP4_GET_PRIVATE (self);
 	GtkTreeModel *model;
-	GtkTreeIter iter;
+	GtkTreeIter tree_iter;
 	const char *method;
 	GArray *dns_servers;
 	GSList *search_domains = NULL;
+	GPtrArray *addresses = NULL;
 	gboolean valid;
-	gchar *str;
+	const char *text;
+	char **items = NULL, **iter;
 
 	/* Method */
 	switch (gtk_combo_box_get_active (priv->method)) {
@@ -344,33 +527,83 @@
 		break;
 	}
 
-	/* DNS servers */
-	dns_servers = g_array_new (FALSE, FALSE, sizeof (guint));
-	model = gtk_tree_view_get_model (priv->dns_list);
-	valid = gtk_tree_model_get_iter_first (model, &iter);
+	/* IP addresses */
+	model = gtk_tree_view_get_model (priv->addr_list);
+	valid = gtk_tree_model_get_iter_first (model, &tree_iter);
 
+	addresses = g_ptr_array_sized_new (1);
 	while (valid) {
-		struct in_addr tmp_addr;
+		char *str_address = NULL;
+		char *str_netmask = NULL;
+		char *str_gateway = NULL;
+		struct in_addr tmp_addr, tmp_netmask, tmp_gateway = { 0 };
+		GArray *addr;
+		
+		gtk_tree_model_get (model, &tree_iter, COL_ADDRESS, &str_address, -1);
+		gtk_tree_model_get (model, &tree_iter, COL_NETMASK, &str_netmask, -1);
+		gtk_tree_model_get (model, &tree_iter, COL_GATEWAY, &str_gateway, -1);
+
+		if (!str_address || !inet_aton (str_address, &tmp_addr)) {
+			g_warning ("%s: IPv4 address '%s' missing or invalid!",
+			           __func__, str_address ? str_address : "<none>");
+			goto next;
+		}
+
+		if (!str_netmask || !inet_aton (str_netmask, &tmp_netmask)) {
+			g_warning ("%s: IPv4 netmask '%s' missing or invalid!",
+			           __func__, str_netmask ? str_netmask : "<none>");
+			goto next;
+		}
+
+		/* Gateway is optional... */
+		if (str_gateway && !inet_aton (str_gateway, &tmp_gateway)) {
+			g_warning ("%s: IPv4 gateway '%s' missing or invalid!",
+			           __func__, str_gateway ? str_gateway : "<none>");
+			goto next;
+		}
 
-		str = NULL;
-		gtk_tree_model_get (model, &iter, 0, &str, -1);
+		addr = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 3);
+		g_array_append_val (addr, tmp_addr.s_addr);
+		g_array_append_val (addr, tmp_netmask.s_addr);
+		if (tmp_gateway.s_addr)
+			g_array_append_val (addr, tmp_gateway.s_addr);
+		g_ptr_array_add (addresses, addr);
 
-		if (str && inet_aton (str, &tmp_addr))
-			g_array_append_val (dns_servers, tmp_addr.s_addr);
+next:
+		valid = gtk_tree_model_iter_next (model, &tree_iter);
+	}
 
-		g_free (str);
-		valid = gtk_tree_model_iter_next (model, &iter);
+	if (!addresses->len) {
+		g_ptr_array_free (addresses, TRUE);
+		addresses = NULL;
+	}
+
+	/* DNS servers */
+	dns_servers = g_array_new (FALSE, FALSE, sizeof (guint));
+
+	text = gtk_entry_get_text (GTK_ENTRY (priv->dns_servers));
+	if (text && strlen (text)) {
+		items = g_strsplit (text, ",", 0);
+		for (iter = items; *iter; iter++) {
+			struct in_addr tmp_addr;
+
+			if (inet_aton (g_strstrip (*iter), &tmp_addr))
+				g_array_append_val (dns_servers, tmp_addr.s_addr);
+		}
+
+		if (items)
+			g_strfreev (items);
 	}
 
 	/* Search domains */
-	model = gtk_tree_view_get_model (priv->search_list);
-	valid = gtk_tree_model_get_iter_first (model, &iter);
+	text = gtk_entry_get_text (GTK_ENTRY (priv->dns_searches));
+	if (text && strlen (text)) {
+		items = g_strsplit (text, ",", 0);
+		for (iter = items; *iter; iter++)
+			search_domains = g_slist_prepend (search_domains, g_strdup (g_strstrip (*iter)));
 
-	while (valid) {
-		str = NULL;
-		gtk_tree_model_get (model, &iter, 0, &str, -1);
-		search_domains = g_slist_prepend (search_domains, str);
-		valid = gtk_tree_model_iter_next (model, &iter);
+		if (items)
+			g_strfreev (items);
 	}
 
 	search_domains = g_slist_reverse (search_domains);
@@ -378,10 +611,16 @@
 	/* Update setting */
 	g_object_set (priv->setting,
 				  NM_SETTING_IP4_CONFIG_METHOD, method,
+				  NM_SETTING_IP4_CONFIG_ADDRESSES, addresses,
 				  NM_SETTING_IP4_CONFIG_DNS, dns_servers,
 				  NM_SETTING_IP4_CONFIG_DNS_SEARCH, search_domains,
 				  NULL);
 
+	if (addresses) {
+		g_ptr_array_foreach (addresses, (GFunc) free_one_addr, NULL);
+		g_ptr_array_free (addresses, TRUE);
+	}
+
 	g_array_free (dns_servers, TRUE);
 	g_slist_foreach (search_domains, (GFunc) g_free, NULL);
 	g_slist_free (search_domains);

Modified: trunk/src/gconf-helpers/gconf-helpers.c
==============================================================================
--- trunk/src/gconf-helpers/gconf-helpers.c	(original)
+++ trunk/src/gconf-helpers/gconf-helpers.c	Tue Apr 15 18:15:40 2008
@@ -38,6 +38,9 @@
 #include "gconf-upgrade.h"
 #include "utils.h"
 
+#define DBUS_TYPE_G_ARRAY_OF_UINT          (dbus_g_type_get_collection ("GArray", G_TYPE_UINT))
+#define DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_ARRAY_OF_UINT))
+
 const char *applet_8021x_ignore_keys[] = {
 	"ca-cert",
 	"client-cert",
@@ -398,6 +401,57 @@
 }
 
 gboolean
+nm_gconf_get_ip4_addresses_helper (GConfClient *client,
+						  const char *path,
+						  const char *key,
+						  const char *network,
+						  GPtrArray **value)
+{
+	char *gc_key;
+	GConfValue *gc_value;
+	GPtrArray *array;
+	gboolean success = FALSE;
+
+	g_return_val_if_fail (key != NULL, FALSE);
+	g_return_val_if_fail (network != NULL, FALSE);
+	g_return_val_if_fail (value != NULL, FALSE);
+
+	gc_key = g_strdup_printf ("%s/%s/%s", path, network, key);
+	if (!(gc_value = gconf_client_get (client, gc_key, NULL)))
+		goto out;
+
+	if (gc_value->type == GCONF_VALUE_LIST
+	    && gconf_value_get_list_type (gc_value) == GCONF_VALUE_INT)
+	{
+		GSList *elt;
+		GArray *tuple = NULL;
+
+		array = g_ptr_array_sized_new (1);
+		for (elt = gconf_value_get_list (gc_value); elt != NULL; elt = g_slist_next (elt)) {
+			int i = gconf_value_get_int ((GConfValue *) elt->data);
+
+			if (tuple == NULL)
+				tuple = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 3);
+
+			g_array_append_val (tuple, i);
+
+			/* Got addr, netmask, and gateway, add to ptr array */
+			if (tuple->len == 3) {
+				g_ptr_array_add (array, tuple);
+				tuple = NULL;
+			}
+		}
+
+		*value = array;
+		success = TRUE;
+	}
+
+out:
+	g_free (gc_key);
+	return success;
+}
+
+gboolean
 nm_gconf_set_int_helper (GConfClient *client,
                          const char *path,
                          const char *key,
@@ -635,7 +689,59 @@
 	return TRUE;
 }
 
-#include <unistd.h>
+gboolean
+nm_gconf_set_ip4_addresses_helper (GConfClient *client,
+					  const char *path,
+					  const char *key,
+					  const char *network,
+					  GPtrArray *value)
+{
+	char *gc_key;
+	int i;
+	GSList *list = NULL;
+	gboolean success = FALSE;
+
+	g_return_val_if_fail (key != NULL, FALSE);
+	g_return_val_if_fail (network != NULL, FALSE);
+
+	if (!value)
+		return TRUE;
+
+	gc_key = g_strdup_printf ("%s/%s/%s", path, network, key);
+	if (!gc_key) {
+		g_warning ("Not enough memory to create gconf path");
+		return FALSE;
+	}
+
+	for (i = 0; i < value->len; i++) {
+		GArray *tuple = g_ptr_array_index (value, i);
+
+		if ((tuple->len < 2) || (tuple->len > 3)) {
+			g_warning ("%s: invalid IPv4 address structure!", __func__);
+			goto out;
+		}
+
+		/* IP address */
+		list = g_slist_append (list, GUINT_TO_POINTER (g_array_index (tuple, guint32, 0)));
+		/* Netmask */
+		list = g_slist_append (list, GUINT_TO_POINTER (g_array_index (tuple, guint32, 1)));
+
+		/* Gateway */
+		if (tuple->len == 3)
+			list = g_slist_append (list, GUINT_TO_POINTER (g_array_index (tuple, guint32, 2)));
+		else
+			list = g_slist_append (list, GUINT_TO_POINTER (0));
+	}
+
+	gconf_client_set_list (client, gc_key, GCONF_VALUE_INT, list, NULL);
+	success = TRUE;
+
+out:
+	g_slist_free (list);
+	g_free (gc_key);
+	return success;
+}
+
 GSList *
 nm_gconf_get_all_connections (GConfClient *client)
 {
@@ -655,6 +761,12 @@
 	return connections;
 }
 
+static void
+free_one_addr (gpointer data)
+{
+	g_array_free ((GArray *) data, TRUE);
+}
+
 typedef struct ReadFromGConfInfo {
 	NMConnection *connection;
 	GConfClient *client;
@@ -763,9 +875,18 @@
 			g_object_set (setting, key, a_val, NULL);
 			g_array_free (a_val, TRUE);
 		}
-	} else
+	} else if (type == DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT) {
+		GPtrArray *pa_val = NULL;
+
+		if (nm_gconf_get_ip4_addresses_helper (info->client, info->dir, key, setting->name, &pa_val)) {
+			g_object_set (setting, key, pa_val, NULL);
+			g_ptr_array_foreach (pa_val, (GFunc) free_one_addr, NULL);
+			g_ptr_array_free (pa_val, TRUE);
+		}
+	} else {
 		g_warning ("Unhandled setting property type (read): '%s/%s' : '%s'",
 				 setting->name, key, G_VALUE_TYPE_NAME (value));
+	}
 }
 
 static void
@@ -1006,7 +1127,11 @@
 		nm_gconf_set_uint_array_helper (info->client, info->dir,
 								  key, setting->name,
 								  (GArray *) g_value_get_boxed (value));
- 	} else
+	} else if (type == DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT) {
+		nm_gconf_set_ip4_addresses_helper (info->client, info->dir,
+								  key, setting->name,
+								  (GPtrArray *) g_value_get_boxed (value));
+	} else
 		g_warning ("Unhandled setting property type (write) '%s/%s' : '%s'", 
 				 setting->name, key, g_type_name (type));
 }

Modified: trunk/src/gconf-helpers/gconf-helpers.h
==============================================================================
--- trunk/src/gconf-helpers/gconf-helpers.h	(original)
+++ trunk/src/gconf-helpers/gconf-helpers.h	Tue Apr 15 18:15:40 2008
@@ -105,6 +105,13 @@
 			       const char *network,
 			       GHashTable **value);
 
+gboolean
+nm_gconf_get_ip4_addresses_helper (GConfClient *client,
+						  const char *path,
+						  const char *key,
+						  const char *network,
+						  GPtrArray **value);
+
 /* Setters */
 
 gboolean
@@ -162,6 +169,13 @@
 			       const char *network,
 			       GHashTable *value);
 
+gboolean
+nm_gconf_set_ip4_addresses_helper (GConfClient *client,
+					  const char *path,
+					  const char *key,
+					  const char *network,
+					  GPtrArray *value);
+
 GSList *
 nm_gconf_get_all_connections (GConfClient *client);
 



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