network-manager-applet r821 - in trunk: . src/connection-editor



Author: dcbw
Date: Tue Aug  5 20:15:18 2008
New Revision: 821
URL: http://svn.gnome.org/viewvc/network-manager-applet?rev=821&view=rev

Log:
2008-08-05  Dan Williams  <dcbw redhat com>

	* src/connection-editor/Makefile.am
	  src/connection-editor/ip4-routes-dialog.c
	  src/connection-editor/ip4-routes-dialog.h
	  src/connection-editor/ce-page-ip4.glade
		- Add a mostly-functional routes editor dialog

	* src/connection-editor/page-ip4.c
		- Hook the routes button up to the routes dialog



Added:
   trunk/src/connection-editor/ip4-routes-dialog.c
   trunk/src/connection-editor/ip4-routes-dialog.h
Modified:
   trunk/ChangeLog
   trunk/src/connection-editor/Makefile.am
   trunk/src/connection-editor/ce-page-ip4.glade
   trunk/src/connection-editor/page-ip4.c

Modified: trunk/src/connection-editor/Makefile.am
==============================================================================
--- trunk/src/connection-editor/Makefile.am	(original)
+++ trunk/src/connection-editor/Makefile.am	Tue Aug  5 20:15:18 2008
@@ -47,7 +47,9 @@
 	page-vpn.h \
 	page-vpn.c \
 	vpn-helpers.h \
-	vpn-helpers.c
+	vpn-helpers.c \
+	ip4-routes-dialog.h \
+	ip4-routes-dialog.c
 
 if NO_POLKIT_GNOME
 nm_connection_editor_SOURCES += \

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 Aug  5 20:15:18 2008
@@ -141,40 +141,24 @@
             <property name="column_spacing">6</property>
             <property name="row_spacing">6</property>
             <child>
-              <widget class="GtkEntry" id="ip4_dhcp_client_id_entry">
-                <property name="visible">True</property>
-                <property name="can_focus">True</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>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkEntry" id="ip4_dns_searches_entry">
+              <widget class="GtkEntry" id="ip4_dns_servers_entry">
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
-                <property name="tooltip_text">Example: lab.gnome.org, gnome.org</property>
+                <property name="tooltip_text">Example: 10.0.0.1, 10.0.0.2</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="y_options"></property>
               </packing>
             </child>
             <child>
-              <widget class="GtkLabel" id="ip4_dhcp_client_id_label">
+              <widget class="GtkLabel" id="ip4_dns_servers_label">
                 <property name="visible">True</property>
                 <property name="xalign">0</property>
-                <property name="label" translatable="yes">DHCP Client ID:</property>
+                <property name="label" translatable="yes">DNS Servers:</property>
               </widget>
               <packing>
-                <property name="top_attach">2</property>
-                <property name="bottom_attach">3</property>
                 <property name="x_options">GTK_FILL</property>
                 <property name="y_options"></property>
               </packing>
@@ -193,28 +177,44 @@
               </packing>
             </child>
             <child>
-              <widget class="GtkLabel" id="ip4_dns_servers_label">
+              <widget class="GtkLabel" id="ip4_dhcp_client_id_label">
                 <property name="visible">True</property>
                 <property name="xalign">0</property>
-                <property name="label" translatable="yes">DNS Servers:</property>
+                <property name="label" translatable="yes">DHCP Client ID:</property>
               </widget>
               <packing>
+                <property name="top_attach">2</property>
+                <property name="bottom_attach">3</property>
                 <property name="x_options">GTK_FILL</property>
                 <property name="y_options"></property>
               </packing>
             </child>
             <child>
-              <widget class="GtkEntry" id="ip4_dns_servers_entry">
+              <widget class="GtkEntry" id="ip4_dns_searches_entry">
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
-                <property name="tooltip_text">Example: 10.0.0.1, 10.0.0.2</property>
+                <property name="tooltip_text">Example: lab.gnome.org, gnome.org</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="y_options"></property>
               </packing>
             </child>
+            <child>
+              <widget class="GtkEntry" id="ip4_dhcp_client_id_entry">
+                <property name="visible">True</property>
+                <property name="can_focus">True</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>
+              </packing>
+            </child>
           </widget>
           <packing>
             <property name="expand">False</property>
@@ -283,4 +283,115 @@
       </widget>
     </child>
   </widget>
+  <widget class="GtkDialog" id="ip4_routes_dialog">
+    <property name="width_request">450</property>
+    <property name="height_request">250</property>
+    <property name="border_width">5</property>
+    <property name="modal">True</property>
+    <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+    <property name="icon_name">stock-peferences</property>
+    <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</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">15</property>
+        <child>
+          <widget class="GtkHBox" id="hbox5">
+            <property name="visible">True</property>
+            <property name="spacing">6</property>
+            <child>
+              <widget class="GtkScrolledWindow" id="scrolledwindow2">
+                <property name="visible">True</property>
+                <property name="can_focus">True</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>
+                <child>
+                  <widget class="GtkTreeView" id="ip4_routes">
+                    <property name="height_request">100</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="tooltip_text">Routes help determine how traffic leaving your computer flows over the network.  Click the "Add" button to add a new route.</property>
+                    <property name="rules_hint">True</property>
+                  </widget>
+                </child>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkVButtonBox" id="vbuttonbox2">
+                <property name="visible">True</property>
+                <property name="spacing">6</property>
+                <property name="layout_style">GTK_BUTTONBOX_START</property>
+                <child>
+                  <widget class="GtkButton" id="ip4_route_add_button">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="can_default">True</property>
+                    <property name="label">gtk-add</property>
+                    <property name="use_stock">True</property>
+                    <property name="response_id">0</property>
+                  </widget>
+                </child>
+                <child>
+                  <widget class="GtkButton" id="ip4_route_delete_button">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="can_default">True</property>
+                    <property name="label">gtk-delete</property>
+                    <property name="use_stock">True</property>
+                    <property name="response_id">0</property>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="position">1</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="cancel_button">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="yes">gtk-cancel</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">-6</property>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkButton" id="ok_button">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="yes">gtk-ok</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">-5</property>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">GTK_PACK_END</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
 </glade-interface>

Added: trunk/src/connection-editor/ip4-routes-dialog.c
==============================================================================
--- (empty file)
+++ trunk/src/connection-editor/ip4-routes-dialog.c	Tue Aug  5 20:15:18 2008
@@ -0,0 +1,332 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Connection editor -- Connection editor for NetworkManager
+ *
+ * Dan Williams <dcbw redhat com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2008 Red Hat, Inc.
+ */
+
+#include <netinet/in.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+
+#include <glade/glade.h>
+#include <glib/gi18n.h>
+
+#include "ip4-routes-dialog.h"
+
+#define COL_ADDRESS 0
+#define COL_PREFIX  1
+#define COL_GATEWAY 2
+#define COL_METRIC  3
+
+static void
+route_add_clicked (GtkButton *button, gpointer user_data)
+{
+	GladeXML *xml = GLADE_XML (user_data);
+	GtkWidget *widget;
+	GtkListStore *store;
+	GtkTreeIter iter;
+	GtkTreeSelection *selection;
+	GtkTreeViewColumn *column;
+	GtkTreePath *path;
+	GList *cells;
+
+	widget = glade_xml_get_widget (xml, "ip4_routes");
+	store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (widget)));
+	gtk_list_store_append (store, &iter);
+	gtk_list_store_set (store, &iter, 0, g_strdup (""), -1);
+
+	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
+	gtk_tree_selection_select_iter (selection, &iter);
+
+	path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter);
+	column = gtk_tree_view_get_column (GTK_TREE_VIEW (widget), 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 (GTK_TREE_VIEW (widget), path, column, cells->data, TRUE);
+
+	g_list_free (cells);
+	gtk_tree_path_free (path);
+}
+
+static void
+route_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)
+		return;
+
+	selected_rows = gtk_tree_selection_get_selected_rows (selection, &model);
+	if (!selected_rows)
+		return;
+
+	if (gtk_tree_model_get_iter (model, &iter, (GtkTreePath *) selected_rows->data))
+		gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+
+	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
+list_selection_changed (GtkTreeSelection *selection, gpointer user_data)
+{
+	GtkWidget *button = GTK_WIDGET (user_data);
+	GtkTreeIter iter;
+	GtkTreeModel *model = NULL;
+
+	if (gtk_tree_selection_get_selected (selection, &model, &iter))
+		gtk_widget_set_sensitive (button, TRUE);
+	else
+		gtk_widget_set_sensitive (button, FALSE);
+}
+
+static void
+cell_edited (GtkCellRendererText *cell,
+             const gchar *path_string,
+             const gchar *new_text,
+             gpointer user_data)
+{
+	GladeXML *xml = GLADE_XML (user_data);
+	GtkWidget *widget;
+	GtkListStore *store;
+	GtkTreePath *path;
+	GtkTreeIter iter;
+	guint32 column;
+
+	widget = glade_xml_get_widget (xml, "ip4_routes");
+	store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (widget)));
+	path = gtk_tree_path_new_from_string (path_string);
+	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);
+}
+
+GtkWidget *
+ip4_routes_dialog_new (GSList *routes)
+{
+	GladeXML *xml;
+	GtkWidget *dialog, *widget;
+	GSList *iter;
+	GtkListStore *store;
+	GtkTreeIter model_iter;
+	GtkTreeSelection *selection;
+	gint offset;
+	GtkTreeViewColumn *column;
+	GtkCellRenderer *renderer;
+
+	xml = glade_xml_new (GLADEDIR "/ce-page-ip4.glade", "ip4_routes_dialog", NULL);
+	if (!xml) {
+		g_warning ("%s: Couldn't load ip4 page glade file.", __func__);
+		return NULL;
+	}
+
+	dialog = glade_xml_get_widget (xml, "ip4_routes_dialog");
+	if (!dialog) {
+		g_warning ("%s: Couldn't load ip4 routes dialog from glade file.", __func__);
+		g_object_unref (xml);
+		return NULL;
+	}
+
+	gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+
+	g_object_set_data_full (G_OBJECT (dialog), "glade-xml",
+	                        xml, (GDestroyNotify) g_object_unref);
+
+	store = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+
+	/* Add existing routes */
+	for (iter = routes; iter; iter = g_slist_next (iter)) {
+		NMSettingIP4Address *route = (NMSettingIP4Address *) iter->data;
+		struct in_addr tmp_addr;
+		char ip_string[50];
+
+		if (!route) {
+			g_warning ("%s: empty IP4 route structure!", __func__);
+			continue;
+		}
+
+		gtk_list_store_append (store, &model_iter);
+
+		tmp_addr.s_addr = route->address;
+		if (inet_ntop (AF_INET, &tmp_addr, &ip_string[0], sizeof (ip_string)))
+			gtk_list_store_set (store, &model_iter, COL_ADDRESS, g_strdup (ip_string), -1);
+
+		gtk_list_store_set (store, &model_iter, COL_PREFIX, g_strdup_printf ("%d", route->prefix), -1);
+
+		tmp_addr.s_addr = route->gateway;
+		if (inet_ntop (AF_INET, &tmp_addr, &ip_string[0], sizeof (ip_string)))
+			gtk_list_store_set (store, &model_iter, COL_GATEWAY, g_strdup (ip_string), -1);
+
+		gtk_list_store_set (store, &model_iter, COL_METRIC, g_strdup_printf ("%d", 1), -1);
+	}
+
+	widget = glade_xml_get_widget (xml, "ip4_routes");
+	gtk_tree_view_set_model (GTK_TREE_VIEW (widget), GTK_TREE_MODEL (store));
+	g_object_unref (store);
+
+	/* 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), xml);
+	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 (GTK_TREE_VIEW (widget),
+	                                                      -1, _("Address"), renderer,
+	                                                      "text", COL_ADDRESS,
+	                                                      NULL);
+	column = gtk_tree_view_get_column (GTK_TREE_VIEW (widget), 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);
+
+	/* Prefix column */
+	renderer = gtk_cell_renderer_text_new ();
+	g_object_set (renderer, "editable", TRUE, NULL);
+	g_signal_connect (renderer, "edited", G_CALLBACK (cell_edited), xml);
+	g_object_set_data (G_OBJECT (renderer), "column", GUINT_TO_POINTER (COL_PREFIX));
+	g_signal_connect (renderer, "editing-started", G_CALLBACK (cell_editing_started), store);
+
+	offset = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (widget),
+	                                                      -1, _("Prefix"), renderer,
+	                                                      "text", COL_PREFIX,
+	                                                      NULL);
+	column = gtk_tree_view_get_column (GTK_TREE_VIEW (widget), 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), xml);
+	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 (GTK_TREE_VIEW (widget),
+	                                                      -1, _("Gateway"), renderer,
+	                                                      "text", COL_GATEWAY,
+	                                                      NULL);
+	column = gtk_tree_view_get_column (GTK_TREE_VIEW (widget), 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);
+
+	/* Metric column */
+	renderer = gtk_cell_renderer_text_new ();
+	g_object_set (renderer, "editable", TRUE, NULL);
+	g_signal_connect (renderer, "edited", G_CALLBACK (cell_edited), xml);
+	g_object_set_data (G_OBJECT (renderer), "column", GUINT_TO_POINTER (COL_METRIC));
+	g_signal_connect (renderer, "editing-started", G_CALLBACK (cell_editing_started), store);
+
+	offset = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (widget),
+	                                                      -1, _("Metric"), renderer,
+	                                                      "text", COL_METRIC,
+	                                                      NULL);
+	column = gtk_tree_view_get_column (GTK_TREE_VIEW (widget), 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);
+
+
+	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
+	g_signal_connect (selection, "changed",
+	                  G_CALLBACK (list_selection_changed),
+	                  glade_xml_get_widget (xml, "ip4_route_delete_button"));
+
+	widget = glade_xml_get_widget (xml, "ip4_route_add_button");
+	gtk_widget_set_sensitive (widget, TRUE);
+	g_signal_connect (widget, "clicked", G_CALLBACK (route_add_clicked), xml);
+
+	widget = glade_xml_get_widget (xml, "ip4_route_delete_button");
+	gtk_widget_set_sensitive (widget, FALSE);
+	g_signal_connect (widget, "clicked",
+	                  G_CALLBACK (route_delete_clicked),
+	                  glade_xml_get_widget (xml, "ip4_routes"));
+
+	return dialog;
+}
+
+void
+ip4_routes_dialog_update_setting (GtkWidget *dialog, NMSettingIP4Config *s_ip4)
+{
+}
+

Added: trunk/src/connection-editor/ip4-routes-dialog.h
==============================================================================
--- (empty file)
+++ trunk/src/connection-editor/ip4-routes-dialog.h	Tue Aug  5 20:15:18 2008
@@ -0,0 +1,35 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Connection editor -- Connection editor for NetworkManager
+ *
+ * Dan Williams <dcbw redhat com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2008 Red Hat, Inc.
+ */
+
+#ifndef IP4_ROUTES_DIALOG_H
+#define IP4_ROUTES_DIALOG_H
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+#include "nm-setting-ip4-config.h"
+
+GtkWidget *ip4_routes_dialog_new (GSList *routes);
+
+void ip4_routes_dialog_update_setting (GtkWidget *dialog, NMSettingIP4Config *s_ip4);
+
+#endif /* IP4_ROUTES_DIALOG_H */

Modified: trunk/src/connection-editor/page-ip4.c
==============================================================================
--- trunk/src/connection-editor/page-ip4.c	(original)
+++ trunk/src/connection-editor/page-ip4.c	Tue Aug  5 20:15:18 2008
@@ -35,6 +35,7 @@
 #include <nm-setting-vpn.h>
 
 #include "page-ip4.h"
+#include "ip4-routes-dialog.h"
 
 G_DEFINE_TYPE (CEPageIP4, ce_page_ip4, CE_TYPE_PAGE)
 
@@ -42,6 +43,7 @@
 
 typedef struct {
 	NMSettingIP4Config *setting;
+	char *connection_id;
 
 	GtkComboBox *method;
 	GtkListStore *method_store;
@@ -66,7 +68,8 @@
 
 	GtkButton *routes_button;
 
-	gboolean disposed;
+	GtkWindowGroup *window_group;
+	gboolean window_added;
 } CEPageIP4Private;
 
 #define METHOD_COL_NAME 0
@@ -470,6 +473,57 @@
 	                  data);
 }
 
+static void
+routes_dialog_close_cb (GtkWidget *dialog, gpointer user_data)
+{
+	gtk_widget_hide (dialog);
+	/* gtk_widget_destroy() will remove the window from the window group */
+	gtk_widget_destroy (dialog);
+}
+
+static void
+routes_dialog_response_cb (GtkWidget *dialog, gint response, gpointer user_data)
+{
+	CEPageIP4 *self = CE_PAGE_IP4 (user_data);
+	CEPageIP4Private *priv = CE_PAGE_IP4_GET_PRIVATE (self);
+
+	if (response == GTK_RESPONSE_OK)
+		ip4_routes_dialog_update_setting (dialog, priv->setting);
+
+	routes_dialog_close_cb (dialog, NULL);
+}
+
+static void
+routes_button_clicked_cb (GtkWidget *button, gpointer user_data)
+{
+	CEPageIP4 *self = CE_PAGE_IP4 (user_data);
+	CEPageIP4Private *priv = CE_PAGE_IP4_GET_PRIVATE (self);
+	GtkWidget *dialog, *toplevel;
+
+	toplevel = gtk_widget_get_toplevel (CE_PAGE (self)->page);
+	g_return_if_fail (GTK_WIDGET_TOPLEVEL (toplevel));
+
+	dialog = ip4_routes_dialog_new (priv->setting->routes);
+	if (!dialog) {
+		g_warning ("%s: failed to create the routes dialog!", __func__);
+		return;
+	}
+
+	gtk_window_group_add_window (priv->window_group, GTK_WINDOW (dialog));
+	if (!priv->window_added) {
+		gtk_window_group_add_window (priv->window_group, GTK_WINDOW (toplevel));
+		priv->window_added = TRUE;
+	}
+
+	gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (toplevel));
+	gtk_window_set_title (GTK_WINDOW (dialog), g_strdup_printf (_("Editing IPv4 routes for %s"), priv->connection_id));
+
+	g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (routes_dialog_response_cb), self);
+	g_signal_connect (G_OBJECT (dialog), "close", G_CALLBACK (routes_dialog_close_cb), self);
+
+	gtk_widget_show_all (dialog);
+}
+
 CEPageIP4 *
 ce_page_ip4_new (NMConnection *connection)
 {
@@ -506,12 +560,16 @@
 
 	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
 	g_assert (s_con && s_con->type);
+
 	if (!strcmp (s_con->type, NM_SETTING_VPN_SETTING_NAME))
 		is_vpn = TRUE;
 
 	ip4_private_init (self, is_vpn);
 	priv = CE_PAGE_IP4_GET_PRIVATE (self);
 
+	priv->window_group = gtk_window_group_new ();
+	priv->connection_id = g_strdup (s_con->id);
+
 	priv->setting = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
 	if (!priv->setting) {
 		priv->setting = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ());
@@ -584,6 +642,8 @@
 
 	g_signal_connect_swapped (priv->dhcp_client_id, "changed", G_CALLBACK (ce_page_changed), self);
 
+	g_signal_connect (priv->routes_button, "clicked", G_CALLBACK (routes_button_clicked_cb), self);
+
 	return self;
 }
 
@@ -783,6 +843,20 @@
 }
 
 static void
+dispose (GObject *object)
+{
+	CEPageIP4 *self = CE_PAGE_IP4 (object);
+	CEPageIP4Private *priv = CE_PAGE_IP4_GET_PRIVATE (self);
+
+	if (priv->window_group)
+		g_object_unref (priv->window_group);
+
+	g_free (priv->connection_id);
+
+	G_OBJECT_CLASS (ce_page_ip4_parent_class)->dispose (object);
+}
+
+static void
 ce_page_ip4_class_init (CEPageIP4Class *ip4_class)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (ip4_class);
@@ -792,4 +866,5 @@
 
 	/* virtual methods */
 	parent_class->validate = validate;
+	object_class->dispose = dispose;
 }



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