From bbc6434e96b013740df4d3ef35ccf988f20afe0a Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Thu, 27 Feb 2014 14:03:22 -0500 Subject: [PATCH] tui: fix selection bugs after deleting a connection nmt_newt_listbox_clear() did not reset active and active_key, which in the case of NmtEditConnectionList meant that after the connection list was rebuilt, the selection would appear to be in the same place, but active_key would still point to the connection that used to be in that row, rather than the one currently in that row, so if you immediately hit Edit or Delete, you'd get unexpected results. (It also meant that it was possible for the selection to land on a header row instead of a connection row.) This was particularly bad in the case of the Delete button, since active_key would be left pointing to a freed NMConnection in that case. Fix NmtNewtListbox, and then add code to NmtEditConnectionList to preserve the selection itself when rebuilding the list. --- tui/newt/nmt-newt-listbox.c | 4 ++++ tui/nmt-edit-connection-list.c | 38 +++++++++++++++++++++++++--------- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/tui/newt/nmt-newt-listbox.c b/tui/newt/nmt-newt-listbox.c index 2e3655aaa4..78c55dbe31 100644 --- a/tui/newt/nmt-newt-listbox.c +++ b/tui/newt/nmt-newt-listbox.c @@ -126,6 +126,10 @@ nmt_newt_listbox_clear (NmtNewtListbox *listbox) g_ptr_array_set_size (priv->entries, 0); g_ptr_array_set_size (priv->keys, 0); + + priv->active = -1; + priv->active_key = NULL; + nmt_newt_widget_needs_rebuild (NMT_NEWT_WIDGET (listbox)); } diff --git a/tui/nmt-edit-connection-list.c b/tui/nmt-edit-connection-list.c index a08ffc75f2..ec0a66845c 100644 --- a/tui/nmt-edit-connection-list.c +++ b/tui/nmt-edit-connection-list.c @@ -181,12 +181,14 @@ static void nmt_edit_connection_list_rebuild (NmtEditConnectionList *list) { NmtEditConnectionListPrivate *priv = NMT_EDIT_CONNECTION_LIST_GET_PRIVATE (list); - NmtNewtListbox *listbox; GSList *iter, *next; gboolean did_header = FALSE, did_vpn = FALSE; NMEditorConnectionTypeData **types; - NMConnection *conn; - int i; + NMConnection *conn, *selected_conn; + int i, row, selected_row; + + selected_row = nmt_newt_listbox_get_active (priv->listbox); + selected_conn = nmt_newt_listbox_get_active_key (priv->listbox); free_connections (list); priv->connections = nm_remote_settings_list_connections (nm_settings); @@ -215,20 +217,25 @@ nmt_edit_connection_list_rebuild (NmtEditConnectionList *list) nmt_newt_component_set_sensitive (NMT_NEWT_COMPONENT (priv->delete), priv->connections != NULL); - listbox = NMT_NEWT_LISTBOX (priv->listbox); - nmt_newt_listbox_clear (listbox); + nmt_newt_listbox_clear (priv->listbox); if (!priv->grouped) { /* Just add the connections in order */ - for (iter = priv->connections; iter; iter = iter->next) { + for (iter = priv->connections, row = 0; iter; iter = iter->next, row++) { conn = iter->data; - nmt_newt_listbox_append (listbox, nm_connection_get_id (conn), conn); + nmt_newt_listbox_append (priv->listbox, nm_connection_get_id (conn), conn); + if (conn == selected_conn) + selected_row = row; } + if (selected_row >= row) + selected_row = row - 1; + nmt_newt_listbox_set_active (priv->listbox, selected_row); + return; } types = nm_editor_utils_get_connection_type_list (); - for (i = 0; types[i]; i++) { + for (i = row = 0; types[i]; i++) { if (types[i]->setting_type == NM_TYPE_SETTING_VPN) { if (did_vpn) continue; @@ -249,15 +256,26 @@ nmt_edit_connection_list_rebuild (NmtEditConnectionList *list) continue; if (!did_header) { - nmt_newt_listbox_append (listbox, types[i]->name, NULL); + nmt_newt_listbox_append (priv->listbox, types[i]->name, NULL); + if (row == selected_row) + selected_row++; + row++; did_header = TRUE; } indented = g_strdup_printf (" %s", nm_connection_get_id (conn)); - nmt_newt_listbox_append (listbox, indented, conn); + nmt_newt_listbox_append (priv->listbox, indented, conn); g_free (indented); + + if (conn == selected_conn) + selected_row = row; + row++; } } + + if (selected_row >= row) + selected_row = row - 1; + nmt_newt_listbox_set_active (priv->listbox, selected_row); } static void