Index: capplets/network/gnome-network-preferences.glade
===================================================================
--- capplets/network/gnome-network-preferences.glade	(revision 9002)
+++ capplets/network/gnome-network-preferences.glade	(working copy)
@@ -26,6 +26,44 @@
       <property name="visible">True</property>
       <property name="homogeneous">False</property>
       <property name="spacing">2</property>
+      <child>
+        <widget class="GtkAlignment" id="alignment1">
+          <property name="xalign">0.5</property>
+          <property name="xscale">0</property>
+          <child>
+            <widget class="GtkHBox" id="hbox2">
+              <property name="visible">True</property>
+              <property name="spacing">3</property>
+              <child>
+                <widget class="GtkLabel" id="label1">
+                  <property name="visible">True</property>
+                  <property name="label" translatable="yes">Location:</property>
+                  <property name="xalign">1</property>
+                </widget>
+                <packing>
+                  <property name="expand">True</property>
+                  <property name="fill">True</property>
+                </packing>
+              </child>
+              <child>
+                <widget class="GtkComboBox" id="location_combobox">
+                  <property name="visible">True</property>
+                </widget>
+                <packing>
+                  <property name="position">1</property>
+                  <property name="expand">True</property>
+                  <property name="fill">True</property>
+                </packing>
+              </child>
+            </widget>
+          </child>
+        </widget>
+        <packing>
+          <property name="expand">False</property>
+          <property name="fill">False</property>
+          <property name="position">1</property>
+        </packing>
+      </child>
 
       <child internal-child="action_area">
 	<widget class="GtkHButtonBox" id="dialog-action_area1">
@@ -44,7 +82,14 @@
 	      <property name="response_id">-11</property>
 	    </widget>
 	  </child>
-
+	  <child>
+		<widget class="GtkButton" id="delete_button">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="sensitive">False</property>
+		  <property name="label" translatable="yes">_Delete Location</property>
+		</widget>
+	  </child>
 	  <child>
 	    <widget class="GtkButton" id="closebutton1">
 	      <property name="visible">True</property>
@@ -1307,6 +1352,105 @@
 	</packing>
       </child>
     </widget>
+  </child>
+</widget>
+<widget class="GtkDialog" id="location_new_dialog">
+  <property name="border_width">5</property>
+  <property name="title" translatable="yes">Create new location:</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="resizable">False</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
+  <property name="has_separator">False</property>
+  <child internal-child="vbox">
+	<widget class="GtkVBox" id="dialog-vbox1">
+	  <property name="visible">True</property>
+	  <property name="spacing">2</property>
+	  <property name="homogeneous">True</property>
+	  <child>
+		<widget class="GtkLabel" id="label19">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Enter a name for the new _location:</property>
+		  <property name="use_underline">True</property>
+		  <property name="use_markup">False</property>
+		  <property name="mnemonic_widget">text</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.5</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">False</property>
+		  <property name="fill">False</property>
+		  <property name="position">1</property>
+		</packing>
+	  </child>
+	  <child>
+		<widget class="GtkEntry" id="text">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="activates_default">True</property>
+		</widget>
+		<packing>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		  <property name="position">2</property>
+		</packing>
+	  </child>
+	  <child internal-child="action_area">
+		<widget class="GtkHButtonBox" id="dialog-action_area1">
+		  <property name="visible">True</property>
+		  <property name="layout_style">GTK_BUTTONBOX_END</property>
+		  <child>
+			<widget class="GtkButton" id="new_location">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="receives_default">True</property>
+			  <property name="label" translatable="yes">C_reate</property>
+			  <property name="use_stock">False</property>
+			  <property name="response_id">-5</property>
+			  <child>
+				<placeholder/>
+			  </child>
+			</widget>
+		  </child>
+		  <child>
+			<widget class="GtkButton" id="button2">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="receives_default">True</property>
+			  <property name="label">gtk-cancel</property>
+			  <property name="use_stock">True</property>
+			  <property name="response_id">-6</property>
+			</widget>
+			<packing>
+			  <property name="position">1</property>
+			</packing>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		  <property name="pack_type">GTK_PACK_END</property>
+		</packing>
+	  </child>
+	</widget>
   </child>
 </widget>
 
Index: capplets/network/gnome-network-preferences.c
===================================================================
--- capplets/network/gnome-network-preferences.c	(revision 9002)
+++ capplets/network/gnome-network-preferences.c	(working copy)
@@ -46,6 +46,11 @@ static GEnumValue proxytype_values[] = {
 	{ 0, NULL, NULL }
 };
 
+enum {
+	COL_NAME,
+	COL_STYLE
+};
+
 #define USE_PROXY_KEY   "/system/http_proxy/use_http_proxy"
 #define USE_SAME_PROXY_KEY   "/system/http_proxy/use_same_proxy"
 #define HTTP_PROXY_HOST_KEY  "/system/http_proxy/host"
@@ -69,6 +74,9 @@ static GEnumValue proxytype_values[] = {
 #define OLD_SOCKS_PROXY_PORT_KEY  "/system/proxy/old_socks_port"
 #define PROXY_AUTOCONFIG_URL_KEY  "/system/proxy/autoconfig_url"
 
+#define LOCATION_DIR "/apps/control-center/network"
+#define CURRENT_LOCATION "/apps/control-center/network/current_location"
+
 static GtkWidget *details_dialog = NULL;
 static GSList *ignore_hosts = NULL;
 static GtkTreeModel *model = NULL;
@@ -177,10 +185,12 @@ static void
 cb_dialog_response (GtkDialog *dialog, gint response_id)
 {
 	if (response_id == GTK_RESPONSE_HELP)
+	{
 		capplet_help (GTK_WINDOW (dialog),
 			"user-guide.xml",
 			"goscustdesk-50");
-	else
+	}
+	else if (response_id == GTK_RESPONSE_CLOSE || response_id == GTK_RESPONSE_DELETE_EVENT)
 	{
 		if (ignore_hosts) {
 			g_slist_foreach (ignore_hosts, (GFunc) g_free, NULL);
@@ -257,6 +267,534 @@ cb_http_details_button_clicked (GtkWidge
 	gtk_widget_show_all (widget);
 }
 
+static gchar *
+copy_location_create_key (const gchar *from, const gchar *what)
+{
+	if (from[0] == '\0') return g_strdup (what);
+	else return g_strconcat (from, what + strlen ("/system"), NULL);
+}
+
+static void
+copy_location (const gchar *from, const gchar *to, GConfClient *client)
+{
+	int ti;
+	gboolean tb;
+	GSList *tl;
+	gchar *tstr, *dest, *src;
+
+	if (from[0] != '\0' && !gconf_client_dir_exists (client, from, NULL))
+		return;
+
+	/* USE_PROXY */
+	dest = copy_location_create_key (to, USE_PROXY_KEY);
+	src = copy_location_create_key (from, USE_PROXY_KEY);
+
+	tb = gconf_client_get_bool (client, src, NULL);
+	gconf_client_set_bool (client, dest, tb, NULL);
+
+	g_free (dest);
+	g_free (src);
+
+	/* USE_SAME_PROXY */
+	dest = copy_location_create_key (to, USE_SAME_PROXY_KEY);
+	src = copy_location_create_key (from, USE_SAME_PROXY_KEY);
+
+	tb = gconf_client_get_bool (client, src, NULL);
+	gconf_client_set_bool (client, dest, tb, NULL);
+
+	g_free (dest);
+	g_free (src);
+
+	/* HTTP_PROXY_HOST */
+	dest = copy_location_create_key (to, HTTP_PROXY_HOST_KEY);
+	src = copy_location_create_key (from, HTTP_PROXY_HOST_KEY);
+
+	tstr = gconf_client_get_string (client, src, NULL);
+	if (tstr != NULL)
+	{
+		gconf_client_set_string (client, dest, tstr, NULL);
+		g_free (tstr);
+	}
+
+	g_free (dest);
+	g_free (src);
+
+	/* HTTP_PROXY_PORT */
+	dest = copy_location_create_key (to, HTTP_PROXY_PORT_KEY);
+	src = copy_location_create_key (from, HTTP_PROXY_PORT_KEY);
+
+	ti = gconf_client_get_int (client, src, NULL);
+	gconf_client_set_int (client, dest, ti, NULL);
+
+	g_free (dest);
+	g_free (src);
+
+	/* HTTP_USE_AUTH */
+	dest = copy_location_create_key (to, HTTP_USE_AUTH_KEY);
+	src = copy_location_create_key (from, HTTP_USE_AUTH_KEY);
+
+	tb = gconf_client_get_bool (client, src, NULL);
+	gconf_client_set_bool (client, dest, tb, NULL);
+
+	g_free (dest);
+	g_free (src);
+
+	/* HTTP_AUTH_USER */
+	dest = copy_location_create_key (to, HTTP_AUTH_USER_KEY);
+	src = copy_location_create_key (from, HTTP_AUTH_USER_KEY);
+
+	tstr = gconf_client_get_string (client, src, NULL);
+	if (tstr != NULL)
+	{
+		gconf_client_set_string (client, dest, tstr, NULL);
+		g_free (tstr);
+	}
+
+	g_free (dest);
+	g_free (src);
+
+	/* HTTP_AUTH_PASSWD */
+	dest = copy_location_create_key (to, HTTP_AUTH_PASSWD_KEY);
+	src = copy_location_create_key (from, HTTP_AUTH_PASSWD_KEY);
+
+	tstr = gconf_client_get_string (client, src, NULL);
+	if (tstr != NULL)
+	{
+		 gconf_client_set_string (client, dest, tstr, NULL);
+		g_free (tstr);
+	}
+
+	g_free (dest);
+	g_free (src);
+
+	/* IGNORE_HOSTS */
+	dest = copy_location_create_key (to, IGNORE_HOSTS_KEY);
+	src = copy_location_create_key (from, IGNORE_HOSTS_KEY);
+
+	tl = gconf_client_get_list (client, src, GCONF_VALUE_STRING, NULL);
+	gconf_client_set_list (client, dest, GCONF_VALUE_STRING, tl, NULL);
+	g_slist_foreach (tl, (GFunc) g_free, NULL);
+	g_slist_free (tl);
+
+	g_free (dest);
+	g_free (src);
+
+	/* PROXY_MODE */
+	dest = copy_location_create_key (to, PROXY_MODE_KEY);
+	src = copy_location_create_key (from, PROXY_MODE_KEY);
+
+	tstr = gconf_client_get_string (client, src, NULL);
+	if (tstr != NULL)
+	{
+		gconf_client_set_string (client, dest, tstr, NULL);
+		g_free (tstr);
+	}
+
+	g_free (dest);
+	g_free (src);
+
+	/* SECURE_PROXY_HOST */
+	dest = copy_location_create_key (to, SECURE_PROXY_HOST_KEY);
+	src = copy_location_create_key (from, SECURE_PROXY_HOST_KEY);
+
+	tstr = gconf_client_get_string (client, src, NULL);
+	if (tstr != NULL)
+	{
+		gconf_client_set_string (client, dest, tstr, NULL);
+		g_free (tstr);
+	}
+
+	g_free (dest);
+	g_free (src);
+
+	/* OLD_SECURE_PROXY_HOST */
+	dest = copy_location_create_key (to, OLD_SECURE_PROXY_HOST_KEY);
+	src = copy_location_create_key (from, OLD_SECURE_PROXY_HOST_KEY);
+
+	tstr = gconf_client_get_string (client, src, NULL);
+	if (tstr != NULL)
+	{
+		gconf_client_set_string (client, dest, tstr, NULL);
+		g_free (tstr);
+	}
+
+	g_free (dest);
+	g_free (src);
+
+	/* SECURE_PROXY_PORT */
+	dest = copy_location_create_key (to, SECURE_PROXY_PORT_KEY);
+	src = copy_location_create_key (from, SECURE_PROXY_PORT_KEY);
+
+	ti = gconf_client_get_int (client, src, NULL);
+	gconf_client_set_int (client, dest, ti, NULL);
+
+	g_free (dest);
+	g_free (src);
+
+	/* OLD_SECURE_PROXY_PORT */
+	dest = copy_location_create_key (to, OLD_SECURE_PROXY_PORT_KEY);
+	src = copy_location_create_key (from, OLD_SECURE_PROXY_PORT_KEY);
+
+	ti = gconf_client_get_int (client, src, NULL);
+	gconf_client_set_int (client, dest, ti, NULL);
+
+	g_free (dest);
+	g_free (src);
+
+	/* FTP_PROXY_HOST */
+	dest = copy_location_create_key (to, FTP_PROXY_HOST_KEY);
+	src = copy_location_create_key (from, FTP_PROXY_HOST_KEY);
+
+	tstr = gconf_client_get_string (client, src, NULL);
+	if (tstr != NULL)
+	{
+		gconf_client_set_string (client, dest, tstr, NULL);
+		g_free (tstr);
+	}
+
+	g_free (dest);
+	g_free (src);
+
+	/* OLD_FTP_PROXY_HOST */
+	dest = copy_location_create_key (to, OLD_FTP_PROXY_HOST_KEY);
+	src = copy_location_create_key (from, OLD_FTP_PROXY_HOST_KEY);
+
+	tstr = gconf_client_get_string (client, src, NULL);
+	if (tstr != NULL)
+	{
+		gconf_client_set_string (client, dest, tstr, NULL);
+		g_free (tstr);
+	}
+
+	g_free (dest);
+	g_free (src);
+
+	/* FTP_PROXY_PORT */
+	dest = copy_location_create_key (to, FTP_PROXY_PORT_KEY);
+	src = copy_location_create_key (from, FTP_PROXY_PORT_KEY);
+
+	ti = gconf_client_get_int (client, src, NULL);
+	gconf_client_set_int (client, dest, ti, NULL);
+
+	g_free (dest);
+	g_free (src);
+
+	/* OLD_FTP_PROXY_PORT */
+	dest = copy_location_create_key (to, OLD_FTP_PROXY_PORT_KEY);
+	src = copy_location_create_key (from, OLD_FTP_PROXY_PORT_KEY);
+
+	ti = gconf_client_get_int (client, src, NULL);
+	gconf_client_set_int (client, dest, ti, NULL);
+
+	g_free (dest);
+	g_free (src);
+
+	/* SOCKS_PROXY_HOST */
+	dest = copy_location_create_key (to, SOCKS_PROXY_HOST_KEY);
+	src = copy_location_create_key (from, SOCKS_PROXY_HOST_KEY);
+
+	tstr = gconf_client_get_string (client, src, NULL);
+	if (tstr != NULL)
+	{
+		gconf_client_set_string (client, dest, tstr, NULL);
+		g_free (tstr);
+	}
+
+	g_free	(dest);
+	g_free (src);
+
+	/* OLD_SOCKS_PROXY_HOST */
+	dest = copy_location_create_key (to, OLD_SOCKS_PROXY_HOST_KEY);
+	src = copy_location_create_key (from, OLD_SOCKS_PROXY_HOST_KEY);
+
+	tstr = gconf_client_get_string (client, src, NULL);
+	if (tstr != NULL)
+	{
+		gconf_client_set_string (client, dest, tstr, NULL);
+		g_free (tstr);
+	}
+
+	g_free (dest);
+	g_free (src);
+
+	/* SOCKS_PROXY_PORT */
+	dest = copy_location_create_key (to, SOCKS_PROXY_PORT_KEY);
+	src = copy_location_create_key (from, SOCKS_PROXY_PORT_KEY);
+
+	ti = gconf_client_get_int (client, src, NULL);
+	gconf_client_set_int (client, dest, ti, NULL);
+
+	g_free (dest);
+	g_free (src);
+
+	/* OLD_SOCKS_PROXY_PORT */
+	dest = copy_location_create_key (to, OLD_SOCKS_PROXY_PORT_KEY);
+	src = copy_location_create_key (from, OLD_SOCKS_PROXY_PORT_KEY);
+
+	ti = gconf_client_get_int (client, src, NULL);
+	gconf_client_set_int (client, dest, ti, NULL);
+
+	g_free (dest);
+	g_free (src);
+
+	/* PROXY_AUTOCONFIG_URL */
+	dest = copy_location_create_key (to, PROXY_AUTOCONFIG_URL_KEY);
+	src = copy_location_create_key (from, PROXY_AUTOCONFIG_URL_KEY);
+
+	tstr = gconf_client_get_string (client, src, NULL);
+	if (tstr != NULL)
+	{
+		gconf_client_set_string (client, dest, tstr, NULL);
+		g_free (tstr);
+	}
+
+	g_free (dest);
+	g_free (src);
+}
+
+static gchar *
+get_current_location (GConfClient *client)
+{
+	gchar *result;
+
+	result = gconf_client_get_string (client, CURRENT_LOCATION, NULL);
+
+	if (result == NULL || result[0] == '\0')
+	{
+		g_free (result);
+		result = g_strdup (_("Default"));
+	}
+
+	return result;
+}
+
+static gboolean
+location_combo_separator (GtkTreeModel *model,
+			  GtkTreeIter *iter,
+			  gpointer data)
+{
+	gchar *name;
+	gboolean ret;
+
+	gtk_tree_model_get (model, iter, COL_NAME, &name, -1);
+
+	ret = name == NULL || name[0] == '\0';
+
+	g_free (name);
+
+	return ret;
+}
+
+static void
+cb_current_location (GConfClient *client,
+		     guint cnxn_id,
+		     GConfEntry *entry,
+		     GladeXML *dialog)
+{
+	GConfValue *value;
+	const gchar *newval;
+	gchar *key, *esc;
+
+	value = gconf_entry_get_value (entry);
+	if (value == NULL)
+		return;
+
+	newval = gconf_value_get_string (value);
+	if (newval == NULL)
+		return;
+
+	/* copy settings to active slot */
+	esc = gconf_escape_key (newval, -1);
+	key = g_strconcat (LOCATION_DIR "/", esc, NULL);
+	g_free (esc);
+
+	copy_location (key, "", client);
+	gconf_client_recursive_unset (client, key,
+	                              GCONF_UNSET_INCLUDING_SCHEMA_NAMES, NULL);
+	g_free (key);
+}
+
+static void
+update_locations (GConfClient *client,
+		  GladeXML *dialog)
+{
+	int i, select;
+	gchar *current;
+	GtkComboBox *location = GTK_COMBO_BOX (WID ("location_combobox"));
+	GSList *list = gconf_client_all_dirs (client, LOCATION_DIR, NULL);
+	GtkTreeIter titer;
+	GtkListStore *store;
+	GSList *iter;
+
+	store = GTK_LIST_STORE (gtk_combo_box_get_model (location));
+	gtk_list_store_clear (store);
+
+	current = get_current_location (client);
+
+	select = -1;
+	/* FIXME: sort locations by name */
+	for (i = 0, iter = list; iter != NULL; iter = g_slist_next (iter), ++i)
+	{
+		gchar *locp, *key_name;
+
+		locp = iter->data + strlen (LOCATION_DIR) + 1;
+		key_name = gconf_unescape_key (locp, -1);
+
+		gtk_list_store_append (store, &titer);
+		gtk_list_store_set (store, &titer,
+				    COL_NAME, key_name,
+		 		    COL_STYLE, PANGO_STYLE_NORMAL, -1);
+
+		g_free (key_name);
+
+		if (strcmp (locp, current) == 0)
+			select = i;
+	}
+	if (select == -1)
+	{
+		gtk_list_store_append (store, &titer);
+		gtk_list_store_set (store, &titer,
+				    COL_NAME , current,
+				    COL_STYLE, PANGO_STYLE_NORMAL, -1);
+		select = i++;
+	}
+	gtk_widget_set_sensitive (WID ("delete_button"), i > 1);
+
+	gtk_list_store_append (store, &titer);
+	gtk_list_store_set (store, &titer,
+			    COL_NAME, NULL,
+			    COL_STYLE, PANGO_STYLE_NORMAL, -1);
+
+	gtk_list_store_append (store, &titer);
+	gtk_list_store_set (store, &titer,
+			    COL_NAME, _("New Location..."),
+			    COL_STYLE, PANGO_STYLE_ITALIC, -1);
+
+	gtk_combo_box_set_row_separator_func (location, location_combo_separator, NULL, NULL);
+	gtk_combo_box_set_active (location, select);
+	g_free (current);
+	g_slist_foreach (list, (GFunc) gconf_entry_free, NULL);
+	g_slist_free (list);
+}
+
+static void
+location_new (GladeXML *capplet, GtkComboBox *location)
+{
+	GladeXML *dialog;
+	GtkWidget *askdialog;
+	const gchar *name;
+	int response;
+	GConfClient *client;
+
+	client = gconf_client_get_default ();
+
+	dialog = glade_xml_new (GNOMECC_GLADE_DIR "/gnome-network-preferences.glade",
+				"location_new_dialog", NULL);
+
+	gtk_button_set_image (GTK_BUTTON (WID ("new_location")),
+			      gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_BUTTON));
+
+	askdialog = WID ("location_new_dialog");
+	g_signal_connect (askdialog, "response",
+			  G_CALLBACK (gtk_widget_hide), NULL);
+	response = gtk_dialog_run (GTK_DIALOG (askdialog));
+	name = gtk_entry_get_text (GTK_ENTRY (WID ("text")));
+	g_object_unref (dialog);
+
+	/* FIXME: check for duplicates */
+	if (response == GTK_RESPONSE_OK && name[0] != '\0')
+	{
+		gchar *current, *esc, *key;
+
+		current = get_current_location (client);
+		esc = gconf_escape_key (current, -1);
+		g_free (current);
+		key = g_strconcat (LOCATION_DIR "/", esc, NULL);
+		g_free (esc);
+
+		copy_location ("", key, client);
+		g_free (key);
+
+		gconf_client_set_string (client, CURRENT_LOCATION, name, NULL);
+		update_locations (client, capplet);
+	}
+	else
+	{
+		/* switch back to the correct currently selected location */
+		gconf_client_notify (client, CURRENT_LOCATION);
+	}
+	gtk_widget_destroy (askdialog);
+	g_object_unref (client);
+}
+
+static void
+cb_location_changed (GtkWidget *location,
+		     GladeXML *dialog)
+{
+	gchar *current;
+	gchar *name = gtk_combo_box_get_active_text (GTK_COMBO_BOX (location));
+	GConfClient *client;
+
+	if (name == NULL)
+		return;
+
+	client = gconf_client_get_default ();
+
+	current = get_current_location (client);
+
+	if (strcmp (current, name) != 0)
+	{
+		if (strcmp (name, _("New Location...")) == 0)
+		{
+			location_new (dialog, GTK_COMBO_BOX (location));
+		}
+		else
+		{
+			gchar *key, *esc;
+
+			/* save current settings */
+			esc = gconf_escape_key (current, -1);
+			key = g_strconcat (LOCATION_DIR "/", esc, NULL);
+			g_free (esc);
+
+			copy_location ("", key, client);
+			g_free (key);
+
+			gconf_client_set_string (client, CURRENT_LOCATION, name, NULL);
+		}
+	}
+
+	g_free (current);
+	g_free (name);
+	g_object_unref (client);
+}
+
+static void
+cb_delete_button_clicked (GtkWidget *button,
+			  GladeXML *dialog)
+{
+	GConfClient *client;
+	GtkComboBox *box = GTK_COMBO_BOX (WID ("location_combobox"));
+	int active = gtk_combo_box_get_active (box);
+	gchar *current;
+
+	/* prevent the current settings from being saved by blocking
+	 * the signal handler */
+	g_signal_handlers_block_by_func (box, cb_location_changed, dialog);
+	gtk_combo_box_set_active (box, (active == 0) ? 1 : 0);
+	gtk_combo_box_remove_text (box, active);
+	g_signal_handlers_unblock_by_func (box, cb_location_changed, dialog);
+
+	/* set the new location */
+	client = gconf_client_get_default ();
+	current = gtk_combo_box_get_active_text (box);
+	gconf_client_set_string (client, CURRENT_LOCATION, current, NULL);
+	g_free (current);
+	g_object_unref (client);
+
+	/* FIXME: update delete button sensitivity */
+}
+
 static void
 cb_use_same_proxy_checkbutton_clicked (GtkWidget *checkbutton,
 					GladeXML *dialog)
@@ -438,6 +976,9 @@ setup_dialog (GladeXML *dialog)
 	GType mode_type = 0;
 	GConfClient *client;
 	gint port_value;
+	GtkWidget *location_box;
+	GtkCellRenderer *location_renderer;
+	GtkListStore *store;
 
 	mode_type = g_enum_register_static ("NetworkPreferencesProxyType",
 				            proxytype_values);
@@ -445,6 +986,28 @@ setup_dialog (GladeXML *dialog)
 	/* There's a bug in peditors that cause them to not initialize the entry
 	 * correctly. */
 	client = gconf_client_get_default ();
+
+	/* Locations */
+	location_box = WID ("location_combobox");
+	store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
+	gtk_combo_box_set_model (GTK_COMBO_BOX (location_box), GTK_TREE_MODEL (store));
+
+	update_locations (client, dialog);
+	gconf_client_add_dir (client, LOCATION_DIR, GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
+	gconf_client_notify_add (client, CURRENT_LOCATION, (GConfClientNotifyFunc) cb_current_location, dialog, NULL, NULL);
+
+	g_signal_connect (location_box, "changed", G_CALLBACK (cb_location_changed), dialog);
+	g_signal_connect (WID ("delete_button"), "clicked", G_CALLBACK (cb_delete_button_clicked), dialog);
+
+	gtk_button_set_image (GTK_BUTTON (WID ("delete_button")),
+			      gtk_image_new_from_stock (GTK_STOCK_DELETE, GTK_ICON_SIZE_BUTTON));
+
+	location_renderer = gtk_cell_renderer_text_new ();
+	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (location_box), location_renderer, TRUE);
+	gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (location_box),
+					location_renderer,
+					"text", COL_NAME,
+					"style", COL_STYLE, NULL);
 
 	/* Hackety hack */
 	gtk_label_set_use_markup (GTK_LABEL (GTK_BIN (WID ("none_radiobutton"))->child), TRUE);
