[Patch] improve IPv4 setting UI of nm-applet
- From: cee1 <fykcee1 gmail com>
- To: Dan Williams <dcbw redhat com>
- Cc: networkmanager-list gnome org
- Subject: [Patch] improve IPv4 setting UI of nm-applet
- Date: Sun, 10 Jan 2010 16:51:32 +0800
Hi Dan:
Attachment contains a series patches of improving IPv4 setting UI of nm-applet.
These patches aim the following problems:
1) users move focus from a cell of gtktreeview to another widget(i.e. leave gtktreeview) directly, his previous editing will lost.
2) lack of netmask pre-fill for private IPv4 addresses.
3) lack of a proper notification of invalid inputs.
Regards
- cee1
From faa34e5a8719df3204fd267cf400f3bc71e22d65 Mon Sep 17 00:00:00 2001
From: cee1 <fykcee1 gmail com>
Date: Sun, 10 Jan 2010 15:19:21 +0800
Subject: [PATCH 1/5] Edit of addr_box should be saved when focus out
The current UI may lost edit of addr_box, when, e.g. user finished
editing addr/prefix/gateway, then moves focus to DNS entry directly,
the edit of gateway will lost.
This patch handle "editing-canceled" signal of each GtkCellRenderer of
addr/prefix/gateway. It should be a better solution if editing state of
treeview more obvious.
---
src/connection-editor/page-ip4.c | 41 ++++++++++++++++++++++++++++++++++++++
1 files changed, 41 insertions(+), 0 deletions(-)
diff --git a/src/connection-editor/page-ip4.c b/src/connection-editor/page-ip4.c
index 592d8dd..ea72bfc 100644
--- a/src/connection-editor/page-ip4.c
+++ b/src/connection-editor/page-ip4.c
@@ -93,6 +93,11 @@ typedef struct {
#define IP4_METHOD_LINK_LOCAL 3
#define IP4_METHOD_SHARED 4
+static struct {
+ GtkWidget *entry;
+ gchar *path;
+} addr_current_input;
+
static void
ip4_private_init (CEPageIP4 *self, NMConnection *connection)
{
@@ -543,6 +548,14 @@ cell_editing_started (GtkCellRenderer *cell,
return;
}
+ /* keep GTK_ENTRY (editable) alive when received signal "editing-canceled" */
+ if (addr_current_input.entry) {
+ g_object_unref (addr_current_input.entry);
+ g_free (addr_current_input.path);
+ }
+ addr_current_input.entry = g_object_ref (editable);
+ addr_current_input.path = g_strdup (path);
+
/* Set up the entry filter */
g_signal_connect (G_OBJECT (editable), "insert-text",
(GCallback) ip_address_filter_cb,
@@ -550,6 +563,31 @@ cell_editing_started (GtkCellRenderer *cell,
}
static void
+cell_editing_canceled (GtkCellRenderer *renderer, gpointer user_data)
+{
+ CEPageIP4 *self = CE_PAGE_IP4 (user_data);
+ CEPageIP4Private *priv = CE_PAGE_IP4_GET_PRIVATE (self);
+ GtkListStore *store = GTK_LIST_STORE (gtk_tree_view_get_model (priv->addr_list));
+ GtkTreePath *path = gtk_tree_path_new_from_string (addr_current_input.path);
+ const gchar *current_text = gtk_entry_get_text (GTK_ENTRY (addr_current_input.entry));
+ GtkTreeIter iter;
+ guint32 column;
+
+ column = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (renderer), "column"));
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path);
+ gtk_list_store_set (store, &iter, column, current_text, -1);
+
+ gtk_tree_path_free (path);
+ ce_page_changed (CE_PAGE (self));
+
+ /* reset addr_current_input */
+ g_object_unref (addr_current_input.entry);
+ addr_current_input.entry = NULL;
+ g_free (addr_current_input.path);
+ addr_current_input.path = NULL;
+}
+
+static void
routes_dialog_close_cb (GtkWidget *dialog, gpointer user_data)
{
gtk_widget_hide (dialog);
@@ -633,6 +671,7 @@ finish_setup (CEPageIP4 *self, gpointer unused, GError *error, gpointer user_dat
g_signal_connect (renderer, "edited", G_CALLBACK (cell_edited), self);
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);
+ g_signal_connect (renderer, "editing-canceled", G_CALLBACK (cell_editing_canceled), self);
priv->addr_cells[COL_ADDRESS] = GTK_CELL_RENDERER (renderer);
offset = gtk_tree_view_insert_column_with_attributes (priv->addr_list,
@@ -649,6 +688,7 @@ finish_setup (CEPageIP4 *self, gpointer unused, GError *error, gpointer user_dat
g_signal_connect (renderer, "edited", G_CALLBACK (cell_edited), self);
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);
+ g_signal_connect (renderer, "editing-canceled", G_CALLBACK (cell_editing_canceled), self);
priv->addr_cells[COL_PREFIX] = GTK_CELL_RENDERER (renderer);
offset = gtk_tree_view_insert_column_with_attributes (priv->addr_list,
@@ -665,6 +705,7 @@ finish_setup (CEPageIP4 *self, gpointer unused, GError *error, gpointer user_dat
g_signal_connect (renderer, "edited", G_CALLBACK (cell_edited), self);
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);
+ g_signal_connect (renderer, "editing-canceled", G_CALLBACK (cell_editing_canceled), self);
priv->addr_cells[COL_GATEWAY] = GTK_CELL_RENDERER (renderer);
offset = gtk_tree_view_insert_column_with_attributes (priv->addr_list,
--
1.6.5.3
From c902809f140fb611e1c00f1d2b3860ecfc3a4f1d Mon Sep 17 00:00:00 2001
From: cee1 <fykcee1 gmail com>
Date: Sun, 10 Jan 2010 15:42:44 +0800
Subject: [PATCH 2/5] Add netmask prefill for private IPv4 address
---
src/connection-editor/page-ip4.c | 35 +++++++++++++++++++++++++++++++++++
1 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/src/connection-editor/page-ip4.c b/src/connection-editor/page-ip4.c
index ea72bfc..1072a26 100644
--- a/src/connection-editor/page-ip4.c
+++ b/src/connection-editor/page-ip4.c
@@ -543,6 +543,9 @@ cell_editing_started (GtkCellRenderer *cell,
const gchar *path,
gpointer data)
{
+ GtkListStore *store = GTK_LIST_STORE (data);
+ guint32 column;
+
if (!GTK_IS_ENTRY (editable)) {
g_warning ("%s: Unexpected cell editable type.", __func__);
return;
@@ -556,6 +559,38 @@ cell_editing_started (GtkCellRenderer *cell,
addr_current_input.entry = g_object_ref (editable);
addr_current_input.path = g_strdup (path);
+ /* guess DNS for COL_PREFIX */
+ column = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (cell), "column"));
+ if (column == COL_PREFIX) {
+ gchar *guess_prefixes[] = {
+ "255.0.0.0", /* A class */
+ "255.255.0.0", /* B class */
+ "255.255.255.0" /* C class */
+ };
+ const gchar *guess_prefix = NULL;
+ const gchar *prefix = gtk_entry_get_text (GTK_ENTRY (editable));
+
+ gchar *addr;
+ GtkTreeIter iter;
+
+ gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (store), &iter, path);
+ gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, COL_ADDRESS, &addr, -1);
+
+ if (!prefix || !strlen (prefix)) {
+ if (strncmp ("10.", addr, 3) == 0)
+ guess_prefix = guess_prefixes[0];
+ else if (strncmp ("172.16.", addr, 7) == 0)
+ guess_prefix = guess_prefixes[1];
+ else if (strncmp ("192.168.", addr, 8) == 0)
+ guess_prefix = guess_prefixes[2];
+
+ if (guess_prefix)
+ gtk_entry_set_text (GTK_ENTRY (editable), guess_prefix);
+ }
+
+ g_free (addr);
+ }
+
/* Set up the entry filter */
g_signal_connect (G_OBJECT (editable), "insert-text",
(GCallback) ip_address_filter_cb,
--
1.6.5.3
From 741aa425ae9fbd29fceff93135d242f0252504ce Mon Sep 17 00:00:00 2001
From: cee1 <fykcee1 gmail com>
Date: Sun, 10 Jan 2010 16:28:27 +0800
Subject: [PATCH 3/5] Add a label for informing of invalid inputs of IPv4
---
src/connection-editor/ce-page-ip4.glade | 16 ++++++++++-
src/connection-editor/page-ip4.c | 43 +++++++++++++++++++++++++++++-
2 files changed, 55 insertions(+), 4 deletions(-)
diff --git a/src/connection-editor/ce-page-ip4.glade b/src/connection-editor/ce-page-ip4.glade
index 07798fd..d819234 100644
--- a/src/connection-editor/ce-page-ip4.glade
+++ b/src/connection-editor/ce-page-ip4.glade
@@ -52,6 +52,18 @@ Shared to other computers</property>
<property name="visible">True</property>
<property name="spacing">6</property>
<child>
+ <widget class="GtkLabel" id="ip4_addr_info_label">
+ <property name="visible">False</property>
+ <property name="xalign">0.5</property>
+ <property name="use_markup">False</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
<widget class="GtkLabel" id="ip4_addr_label">
<property name="visible">True</property>
<property name="xalign">0</property>
@@ -61,7 +73,7 @@ Shared to other computers</property>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
- <property name="position">0</property>
+ <property name="position">1</property>
</packing>
</child>
<child>
@@ -301,7 +313,7 @@ Shared to other computers</property>
</child>
</widget>
<packing>
- <property name="position">1</property>
+ <property name="position">2</property>
</packing>
</child>
</widget>
diff --git a/src/connection-editor/page-ip4.c b/src/connection-editor/page-ip4.c
index 1072a26..bdd0efd 100644
--- a/src/connection-editor/page-ip4.c
+++ b/src/connection-editor/page-ip4.c
@@ -61,6 +61,7 @@ typedef struct {
/* Addresses */
GtkWidget *addr_label;
+ GtkWidget *addr_info_label;
GtkButton *addr_add;
GtkButton *addr_delete;
GtkTreeView *addr_list;
@@ -179,6 +180,7 @@ ip4_private_init (CEPageIP4 *self, NMConnection *connection)
gtk_combo_box_set_model (priv->method, GTK_TREE_MODEL (priv->method_store));
+ priv->addr_info_label = glade_xml_get_widget (xml, "ip4_addr_info_label");
priv->addr_label = glade_xml_get_widget (xml, "ip4_addr_label");
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"));
@@ -301,6 +303,7 @@ populate_ui (CEPageIP4 *self)
{
CEPageIP4Private *priv = CE_PAGE_IP4_GET_PRIVATE (self);
NMSettingIP4Config *setting = priv->setting;
+ PangoAttrList *attr_list = NULL;
GtkListStore *store;
GtkTreeIter model_iter;
int method = IP4_METHOD_AUTO;
@@ -328,6 +331,15 @@ populate_ui (CEPageIP4 *self)
info.combo = priv->method;
gtk_tree_model_foreach (GTK_TREE_MODEL (priv->method_store), set_method, &info);
+ /* addr info label: set Error reporting color */
+ attr_list = pango_attr_list_new ();
+
+ /* style: red, 11px, bold */
+ pango_attr_list_insert (attr_list, pango_attr_foreground_new (-1, 0, 0));
+ pango_attr_list_insert (attr_list, pango_attr_size_new (11 * PANGO_SCALE));
+ pango_attr_list_insert (attr_list, pango_attr_weight_new (PANGO_WEIGHT_BOLD));
+ gtk_label_set_attributes (GTK_LABEL (priv->addr_info_label), attr_list);
+
/* Addresses */
store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
for (i = 0; i < nm_setting_ip4_config_get_num_addresses (setting); i++) {
@@ -357,7 +369,6 @@ populate_ui (CEPageIP4 *self)
}
gtk_tree_view_set_model (priv->addr_list, GTK_TREE_MODEL (store));
- g_signal_connect_swapped (store, "row-inserted", G_CALLBACK (ce_page_changed), self);
g_signal_connect_swapped (store, "row-deleted", G_CALLBACK (ce_page_changed), self);
g_object_unref (store);
@@ -911,37 +922,65 @@ ui_to_setting (CEPageIP4 *self)
gtk_tree_model_get (model, &tree_iter, COL_ADDRESS, &item, -1);
if (!item || !inet_aton (item, &tmp_addr)) {
+ gboolean empty = !item || !strlen (item);
+ gchar *info = empty ? _("Missing IPv4 address") : \
+ g_strdup_printf (_("Invalid IPv4 address '%s'"), item);
+
g_warning ("%s: IPv4 address '%s' missing or invalid!",
__func__, item ? item : "<none>");
+ gtk_label_set_text (GTK_LABEL (priv->addr_info_label), info);
+ gtk_widget_show (priv->addr_info_label);
+
+ if (!empty) g_free (info);
g_free (item);
+
goto out;
}
g_free (item);
gtk_tree_model_get (model, &tree_iter, COL_PREFIX, &item, -1);
if (!item) {
+ gchar *info = _("Missing IPv4 netmask");
+
g_warning ("%s: IPv4 prefix '%s' missing!",
__func__, item ? item : "<none>");
+ gtk_label_set_text (GTK_LABEL (priv->addr_info_label), info);
+ gtk_widget_show (priv->addr_info_label);
+
goto out;
}
if (!parse_netmask (item, &prefix)) {
+ gchar *info = g_strdup_printf (_("Invalid IPv4 netmask '%s'"), item);
+
g_warning ("%s: IPv4 prefix '%s' invalid!",
__func__, item ? item : "<none>");
+ gtk_label_set_text (GTK_LABEL (priv->addr_info_label), info);
+ gtk_widget_show (priv->addr_info_label);
+ g_free (info);
g_free (item);
+
goto out;
}
g_free (item);
/* Gateway is optional... */
gtk_tree_model_get (model, &tree_iter, COL_GATEWAY, &item, -1);
- if (item && !inet_aton (item, &tmp_gateway)) {
+ if (item && strlen(item) && !inet_aton (item, &tmp_gateway)) {
+ gchar *info = g_strdup_printf (_("Invalid IPv4 gateway '%s'"), item);
+
g_warning ("%s: IPv4 gateway '%s' invalid!",
__func__, item ? item : "<none>");
+ gtk_label_set_text (GTK_LABEL (priv->addr_info_label), info);
+ gtk_widget_show (priv->addr_info_label);
+ g_free (info);
g_free (item);
goto out;
}
g_free (item);
+ /* clear addr info label */
+ gtk_label_set_text (GTK_LABEL (priv->addr_info_label), NULL);
+ gtk_widget_hide (priv->addr_info_label);
addr = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 3);
g_array_append_val (addr, tmp_addr.s_addr);
--
1.6.5.3
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]