static void
connection_updated (NMRemoteConnection *connection, gpointer user_data)
{
	NMConnectionList *self = NM_CONNECTION_LIST (user_data);
	GtkTreeIter iter;

	if (get_iter_for_connection (self, connection, &iter))
		update_connection_row (self, &iter, connection);
}
static void
connection_removed (NMRemoteConnection *connection, gpointer user_data)
{
	NMConnectionList *self = NM_CONNECTION_LIST (user_data);
	GtkTreeIter iter, parent_iter;

	if (get_iter_for_connection (self, connection, &iter)) {
		gtk_tree_model_iter_parent (self->model, &parent_iter, &iter);
		gtk_tree_store_remove (GTK_TREE_STORE (self->model), &iter);
	}
	gtk_tree_model_filter_refilter (self->filter);
}
static void
connection_added (NMRemoteSettings *settings,
                  NMRemoteConnection *connection,
                  gpointer user_data)
{
	NMConnectionList *self = NM_CONNECTION_LIST (user_data);
	GtkTreeIter parent_iter, iter;
	NMSettingConnection *s_con;
	char *last_used;
	gboolean expand = TRUE;

	if (!get_parent_iter_for_connection (self, connection, &parent_iter))
		return;

	s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection));

	last_used = format_last_used (nm_setting_connection_get_timestamp (s_con));

	gtk_tree_store_append (GTK_TREE_STORE (self->model), &iter, &parent_iter);
	gtk_tree_store_set (GTK_TREE_STORE (self->model), &iter,
	                    COL_ID, nm_setting_connection_get_id (s_con),
	                    COL_LAST_USED, last_used,
	                    COL_TIMESTAMP, nm_setting_connection_get_timestamp (s_con),
	                    COL_CONNECTION, connection,
	                    -1);

	g_free (last_used);

	if (self->displayed_type) {
		GType added_type;

		gtk_tree_model_get (self->model, &parent_iter,
		                    COL_GTYPE, &added_type,
		                    -1);
		if (added_type != self->displayed_type)
			expand = FALSE;
	}

	if (expand) {
		GtkTreePath *path, *filtered_path;

		path = gtk_tree_model_get_path (self->model, &parent_iter);
		filtered_path = gtk_tree_model_filter_convert_child_path_to_path (self->filter, path);
		gtk_tree_view_expand_row (self->connection_list, filtered_path, FALSE);
		gtk_tree_path_free (filtered_path);
		gtk_tree_path_free (path);
	}

	g_signal_connect (connection, NM_REMOTE_CONNECTION_REMOVED, G_CALLBACK (connection_removed), self);
	g_signal_connect (connection, NM_REMOTE_CONNECTION_UPDATED, G_CALLBACK (connection_updated), self);
	gtk_tree_model_filter_refilter (self->filter);
}
static void
dispose (GObject *object)
{
	NMConnectionList *list = NM_CONNECTION_LIST (object);

	if (list->dialog)
		gtk_widget_hide (list->dialog);

	if (list->gui)
		g_object_unref (list->gui);
	if (list->nm_client)
		g_object_unref (list->nm_client);

	if (list->settings)
		g_object_unref (list->settings);

	G_OBJECT_CLASS (nm_connection_list_parent_class)->dispose (object);
}
static void
handle_method_call (GDBusConnection       *connection,
                    const gchar           *sender,
                    const gchar           *object_path,
                    const gchar           *interface_name,
                    const gchar           *method_name,
                    GVariant              *parameters,
                    GDBusMethodInvocation *invocation,
                    gpointer               user_data)
{
	NMConnectionList *list = NM_CONNECTION_LIST (user_data);
	char *type = NULL, *uuid = NULL, *import = NULL;
	gboolean create = FALSE, show = FALSE;

	if (g_strcmp0 (method_name, "Start") == 0) {
		if (g_variant_is_of_type (parameters, (const GVariantType *) "(a{sv})")) {
			gs_unref_variant GVariant *dict = NULL;

			g_variant_get (parameters, "(@a{sv})", &dict);
			g_variant_lookup (dict, ARG_TYPE, "s", &type);
			g_variant_lookup (dict, ARG_UUID, "s", &uuid);
			g_variant_lookup (dict, ARG_CREATE, "b", &create);
			g_variant_lookup (dict, ARG_SHOW, "b", &show);
			g_variant_lookup (dict, ARG_IMPORT, "s", &import);
			if (handle_arguments (list, type, create, show, uuid, import, FALSE))
				nm_connection_list_present (list);

			g_dbus_method_invocation_return_value (invocation, NULL);
		} else {
			g_dbus_method_invocation_return_error (invocation,
			                                       G_DBUS_ERROR,
			                                       G_DBUS_ERROR_INVALID_ARGS,
			                                       "Invalid argument type (not a dict)");
		}
	}
}
static void
list_response_cb (GtkDialog *dialog, gint response, gpointer user_data)
{
	g_signal_emit (NM_CONNECTION_LIST (user_data), list_signals[LIST_DONE], 0, response);
}