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.
This commit is contained in:
Dan Winship 2014-02-27 14:03:22 -05:00
parent 01f41506fb
commit bbc6434e96
2 changed files with 32 additions and 10 deletions

View file

@ -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));
}

View file

@ -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