[network-manager-applet] menu: rework and simplify wifi menu item code



commit c962d9fa4baf040798e57ae0eaccaa7ccaa3ab53
Author: Dan Williams <dcbw redhat com>
Date:   Wed Sep 30 22:01:17 2009 -0700

    menu: rework and simplify wifi menu item code
    
    At the same time, never display only one item in the submenu; if there
    are 6 non-active APs, put all 6 in the top-level menu instead of 5
    in the toplevel and one in the submenu.

 src/ap-menu-item.c       |   94 +++++++------
 src/ap-menu-item.h       |   33 +++--
 src/applet-device-wifi.c |  337 +++++++++++++++++++++++----------------------
 src/applet.c             |   68 +---------
 src/applet.h             |    7 -
 5 files changed, 245 insertions(+), 294 deletions(-)
---
diff --git a/src/ap-menu-item.c b/src/ap-menu-item.c
index d890cdd..06db225 100644
--- a/src/ap-menu-item.c
+++ b/src/ap-menu-item.c
@@ -52,7 +52,6 @@ nm_network_menu_item_init (NMNetworkMenuItem * item)
 
 	item->strength = gtk_image_new ();
 	gtk_box_pack_end (GTK_BOX (item->hbox), item->strength, FALSE, TRUE, 0);
-	item->sort_label = g_strdup ("");
 
 	gtk_widget_show (item->ssid);
 	gtk_widget_show (item->strength);
@@ -61,9 +60,9 @@ nm_network_menu_item_init (NMNetworkMenuItem * item)
 }
 
 GtkWidget*
-nm_network_menu_item_new (GtkSizeGroup * size_group,
-                          guchar * hash,
-                          guint32 hash_len)
+nm_network_menu_item_new (guchar *hash,
+                          guint32 hash_len,
+                          gboolean has_connections)
 {
 	NMNetworkMenuItem * item;
 
@@ -71,15 +70,13 @@ nm_network_menu_item_new (GtkSizeGroup * size_group,
 	if (item == NULL)
 		return NULL;
 
-	item->destroyed = FALSE;
-	item->int_strength = 0;
+	item->has_connections = has_connections;
+
 	if (hash && hash_len) {
 		item->hash = g_malloc0 (hash_len);
 		memcpy (item->hash, hash, hash_len);
 		item->hash_len = hash_len;
 	}
-	if (size_group)
-		gtk_size_group_add_widget (size_group, item->detail);
 
 	return GTK_WIDGET (item);
 }
@@ -99,8 +96,6 @@ nm_network_menu_item_class_dispose (GObject *object)
 	gtk_widget_destroy (item->detail);
 	gtk_widget_destroy (item->hbox);
 
-	g_free (item->sort_label);
-
 	item->destroyed = TRUE;
 	g_free (item->hash);
 
@@ -120,13 +115,12 @@ nm_network_menu_item_class_init (NMNetworkMenuItemClass * klass)
 }
 
 void
-nm_network_menu_item_set_ssid (NMNetworkMenuItem * item, GByteArray * ssid)
+nm_network_menu_item_set_ssid (NMNetworkMenuItem *item, GByteArray *ssid)
 {
 	g_return_if_fail (item != NULL);
 	g_return_if_fail (ssid != NULL);
 
 	g_free (item->ssid_string);
-	g_free (item->sort_label);
 
 	item->ssid_string = nm_utils_ssid_to_utf8 ((const char *) ssid->data, ssid->len);
 	if (!item->ssid_string) {
@@ -134,8 +128,12 @@ nm_network_menu_item_set_ssid (NMNetworkMenuItem * item, GByteArray * ssid)
 		item->ssid_string = g_strdup ("<unknown>");
 	}
 	gtk_label_set_text (GTK_LABEL (item->ssid), item->ssid_string);
+}
 
-	item->sort_label = g_strdup (gtk_label_get_text (GTK_LABEL (item->ssid)));
+const char *
+nm_network_menu_item_get_ssid (NMNetworkMenuItem *item)
+{
+	return item->ssid_string;
 }
 
 guint32
@@ -147,44 +145,34 @@ nm_network_menu_item_get_strength (NMNetworkMenuItem * item)
 }
 
 void
-nm_network_menu_item_set_strength (NMNetworkMenuItem * item,
-                                   NMAccessPoint *ap,
-                                   NMApplet *applet)
+nm_network_menu_item_best_strength (NMNetworkMenuItem * item,
+                                    guint8 strength,
+                                    NMApplet *applet)
 {
-	guint8 strength;
 	GdkPixbuf *pixbuf = NULL;
-	guint32 ap_flags, ap_wpa, ap_rsn;
 
 	g_return_if_fail (item != NULL);
 
-	ap_flags = nm_access_point_get_flags (ap);
-	ap_wpa = nm_access_point_get_wpa_flags (ap);
-	ap_rsn = nm_access_point_get_rsn_flags (ap);
-	strength = nm_access_point_get_strength(ap);
 	strength = CLAMP (strength, 0, 100);
 
+	/* Just do nothing if the new strength is less */
+	if (strength < item->int_strength)
+		return;
+
 	item->int_strength = strength;
 
-	if (strength > 80) {
+	if (strength > 80)
 		pixbuf = gdk_pixbuf_copy (applet->wireless_100_icon);
-		item->sort_strength = 4;
-	} else if (strength > 55) {
+	else if (strength > 55)
 		pixbuf = gdk_pixbuf_copy (applet->wireless_75_icon);
-		item->sort_strength = 3;
-	} else if (strength > 30) {
+	else if (strength > 30)
 		pixbuf = gdk_pixbuf_copy (applet->wireless_50_icon);
-		item->sort_strength = 2;
-	} else if (strength > 5) {
+	else if (strength > 5)
 		pixbuf = gdk_pixbuf_copy (applet->wireless_25_icon);
-		item->sort_strength = 1;
-	} else {
+	else
 		pixbuf = gdk_pixbuf_copy (applet->wireless_00_icon);
-		item->sort_strength = 0;
-	}
 
-	if ((ap_flags & NM_802_11_AP_FLAGS_PRIVACY)
-		|| (ap_wpa != NM_802_11_AP_SEC_NONE)
-		|| (ap_rsn != NM_802_11_AP_SEC_NONE)) {
+	if (item->is_encrypted) {
 		GdkPixbuf *top = applet->secure_lock_icon;
 
 		gdk_pixbuf_composite (top, pixbuf, 0, 0, gdk_pixbuf_get_width (top),
@@ -209,9 +197,9 @@ nm_network_menu_item_get_hash (NMNetworkMenuItem * item,
 }
 
 void
-nm_network_menu_item_set_detail (NMNetworkMenuItem * item,
-                                 NMAccessPoint * ap,
-                                 GdkPixbuf * adhoc_icon,
+nm_network_menu_item_set_detail (NMNetworkMenuItem *item,
+                                 NMAccessPoint *ap,
+                                 GdkPixbuf *adhoc_icon,
                                  guint32 dev_caps)
 {
 	gboolean is_adhoc = FALSE;
@@ -221,14 +209,14 @@ nm_network_menu_item_set_detail (NMNetworkMenuItem * item,
 	ap_wpa = nm_access_point_get_wpa_flags (ap);
 	ap_rsn = nm_access_point_get_rsn_flags (ap);
 
-	if (nm_access_point_get_mode (ap) == NM_802_11_MODE_ADHOC)
-		is_adhoc = TRUE;
+	if ((ap_flags & NM_802_11_AP_FLAGS_PRIVACY) || ap_wpa || ap_rsn)
+		item->is_encrypted = TRUE;
 
-	if (is_adhoc) {
+	if (nm_access_point_get_mode (ap) == NM_802_11_MODE_ADHOC) {
+		item->is_adhoc = is_adhoc = TRUE;
 		gtk_image_set_from_pixbuf (GTK_IMAGE (item->detail), adhoc_icon);
-	} else {
+	} else
 		gtk_image_set_from_stock (GTK_IMAGE (item->detail), NULL, GTK_ICON_SIZE_MENU);
-	}
 
 	/* Don't enable the menu item the device can't even connect to the AP */
 	if (   !nm_utils_security_valid (NMU_SEC_NONE, dev_caps, TRUE, is_adhoc, ap_flags, ap_wpa, ap_rsn)
@@ -286,3 +274,21 @@ nm_network_menu_item_add_dupe (NMNetworkMenuItem *item, NMAccessPoint *ap)
 	item->dupes = g_slist_prepend (item->dupes, g_strdup (path));
 }
 
+gboolean
+nm_network_menu_item_get_has_connections (NMNetworkMenuItem *item)
+{
+	return item->has_connections;
+}
+
+gboolean
+nm_network_menu_item_get_is_adhoc (NMNetworkMenuItem *item)
+{
+	return item->is_adhoc;
+}
+
+gboolean
+nm_network_menu_item_get_is_encrypted (NMNetworkMenuItem *item)
+{
+	return item->is_encrypted;
+}
+
diff --git a/src/ap-menu-item.h b/src/ap-menu-item.h
index a457c76..7f82e17 100644
--- a/src/ap-menu-item.h
+++ b/src/ap-menu-item.h
@@ -54,8 +54,9 @@ struct _NMNetworkMenuItem
 	guint32     hash_len;
 	gboolean    destroyed;
 	GSList *    dupes;
-	gchar *sort_label;
-	guint32 sort_strength;
+	gboolean    has_connections;
+	gboolean    is_adhoc;
+	gboolean    is_encrypted;
 };
 
 struct _NMNetworkMenuItemClass
@@ -65,15 +66,21 @@ struct _NMNetworkMenuItemClass
 
 
 GType	   nm_network_menu_item_get_type (void) G_GNUC_CONST;
-GtkWidget* nm_network_menu_item_new (GtkSizeGroup * size_group,
-                                     guchar * hash,
-                                     guint32 hash_len);
-void       nm_network_menu_item_set_ssid (NMNetworkMenuItem * item,
-                                          GByteArray * ssid);
-guint32    nm_network_menu_item_get_strength (NMNetworkMenuItem * item);
-void       nm_network_menu_item_set_strength (NMNetworkMenuItem * item,
-                                              NMAccessPoint *ap,
-                                              NMApplet *applet);
+GtkWidget* nm_network_menu_item_new (guchar *hash,
+                                     guint32 hash_len,
+                                     gboolean has_connections);
+
+void       nm_network_menu_item_set_ssid (NMNetworkMenuItem *item,
+                                          GByteArray *ssid);
+const char *nm_network_menu_item_get_ssid (NMNetworkMenuItem *item);
+
+gboolean   nm_network_menu_item_get_is_adhoc (NMNetworkMenuItem *item);
+gboolean   nm_network_menu_item_get_is_encrypted (NMNetworkMenuItem *item);
+
+guint32    nm_network_menu_item_get_strength (NMNetworkMenuItem *item);
+void       nm_network_menu_item_best_strength (NMNetworkMenuItem *item,
+                                               guint8 strength,
+                                               NMApplet *applet);
 const guchar * nm_network_menu_item_get_hash (NMNetworkMenuItem * item,
                                               guint32 * length);
 void       nm_network_menu_item_set_detail (NMNetworkMenuItem * item,
@@ -89,4 +96,8 @@ void       nm_network_menu_item_add_dupe (NMNetworkMenuItem *item,
 
 void       nm_network_menu_item_set_active (NMNetworkMenuItem * item,
                                             gboolean active);
+
+gboolean   nm_network_menu_item_get_has_connections (NMNetworkMenuItem *item);
+
 #endif /* __AP_MENU_ITEM_H__ */
+
diff --git a/src/applet-device-wifi.c b/src/applet-device-wifi.c
index 459541d..d8992c5 100644
--- a/src/applet-device-wifi.c
+++ b/src/applet-device-wifi.c
@@ -411,9 +411,9 @@ wireless_menu_item_activate (GtkMenuItem *item, gpointer user_data)
 #define AP_HASH_LEN 16
 
 struct dup_data {
-	NMDevice * device;
-	GtkWidget * found;
-	guchar * hash;
+	NMDevice *device;
+	NMNetworkMenuItem *found;
+	guchar *hash;
 };
 
 static void
@@ -441,7 +441,7 @@ find_duplicate (gpointer d, gpointer user_data)
 		return;
 
 	if (memcmp (hash, data->hash, AP_HASH_LEN) == 0)
-		data->found = widget;
+		data->found = NM_NETWORK_MENU_ITEM (widget);
 }
 
 static GSList *
@@ -460,36 +460,32 @@ filter_connections_for_access_point (GSList *connections, NMDeviceWifi *device,
 }
 
 static NMNetworkMenuItem *
-add_new_ap_item (NMDeviceWifi *device,
-                 NMAccessPoint *ap,
-                 struct dup_data *dup_data,
-                 NMAccessPoint *active_ap,
-                 NMConnection *active,
-                 GSList *connections,
-                 NMApplet *applet)
+create_new_ap_item (NMDeviceWifi *device,
+                    NMAccessPoint *ap,
+                    struct dup_data *dup_data,
+                    GSList *connections,
+                    NMApplet *applet)
 {
 	WirelessMenuItemInfo *info;
-	GtkWidget *foo;
 	GSList *iter;
 	NMNetworkMenuItem *item = NULL;
 	GSList *ap_connections = NULL;
 	const GByteArray *ssid;
 	guint32 dev_caps;
-	gboolean is_favorite = FALSE;
 
 	ap_connections = filter_connections_for_access_point (connections, device, ap);
 
-	foo = nm_network_menu_item_new (applet->encryption_size_group,
-	                                dup_data->hash, AP_HASH_LEN);
-	item = NM_NETWORK_MENU_ITEM (foo);
-	gtk_image_menu_item_set_always_show_image(GTK_IMAGE_MENU_ITEM(item), TRUE);
+	item = NM_NETWORK_MENU_ITEM (nm_network_menu_item_new (dup_data->hash,
+	                                                       AP_HASH_LEN,
+	                                                       !!g_slist_length (ap_connections)));
+	gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (item), TRUE);
 
 	ssid = nm_access_point_get_ssid (ap);
 	nm_network_menu_item_set_ssid (item, (GByteArray *) ssid);
 
 	dev_caps = nm_device_wifi_get_capabilities (device);
-	nm_network_menu_item_set_strength (item, ap, applet);
 	nm_network_menu_item_set_detail (item, ap, applet->adhoc_icon, dev_caps);
+	nm_network_menu_item_best_strength (item, nm_access_point_get_strength (ap), applet);
 	nm_network_menu_item_add_dupe (item, ap);
 
 	g_object_set_data (G_OBJECT (item), "device", NM_DEVICE (device));
@@ -522,7 +518,6 @@ add_new_ap_item (NMDeviceWifi *device,
 			gtk_menu_shell_append (GTK_MENU_SHELL (submenu), GTK_WIDGET (subitem));
 		}
 
-		is_favorite = TRUE;
 		gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu);
 	} else {
 		NMConnection *connection;
@@ -535,7 +530,6 @@ add_new_ap_item (NMDeviceWifi *device,
 		if (g_slist_length (ap_connections) == 1) {
 			connection = NM_CONNECTION (g_slist_nth_data (ap_connections, 0));
 			info->connection = g_object_ref (G_OBJECT (connection));
-			is_favorite = TRUE;
 		}
 
 		g_signal_connect_data (GTK_WIDGET (item),
@@ -550,75 +544,62 @@ add_new_ap_item (NMDeviceWifi *device,
 	return item;
 }
 
-
-static GList*
-add_one_ap_menu_item (NMDeviceWifi *device,
+static NMNetworkMenuItem *
+get_menu_item_for_ap (NMDeviceWifi *device,
                       NMAccessPoint *ap,
                       GSList *connections,
-                      NMAccessPoint *active_ap,
-                      NMConnection *active,
-                      GList *menu_list,
+                      GSList *menu_list,
                       NMApplet *applet)
 {
 	const GByteArray *ssid;
 	struct dup_data dup_data = { NULL, NULL };
-	NMNetworkMenuItem *item = NULL;
 
 	/* Don't add BSSs that hide their SSID */
 	ssid = nm_access_point_get_ssid (ap);
 	if (!ssid || nm_utils_is_empty_ssid (ssid->data, ssid->len))
-		return menu_list;
+		return NULL;
 
+	/* Find out if this AP is a member of a larger network that all uses the
+	 * same SSID and security settings.  If so, we'll already have a menu item
+	 * for this SSID, so just update that item's strength and add this AP to
+	 * menu item's duplicate list.
+	 */
 	dup_data.found = NULL;
 	dup_data.hash = g_object_get_data (G_OBJECT (ap), "hash");
 	if (!dup_data.hash)
-		return menu_list;
+		return NULL;
 	dup_data.device = NM_DEVICE (device);
-	g_list_foreach (menu_list,
-	                find_duplicate,
-	                &dup_data);
+	g_slist_foreach (menu_list, find_duplicate, &dup_data);
 
 	if (dup_data.found) {
-		gint8 strength = nm_access_point_get_strength (ap);
-
-		item = NM_NETWORK_MENU_ITEM (dup_data.found);
-
-		/* Just update strength if greater than what's there */
-		if (nm_network_menu_item_get_strength (item) < strength)
-			nm_network_menu_item_set_strength (item, ap, applet);
-
-		nm_network_menu_item_add_dupe (item, ap);
-	} else {
-		item = add_new_ap_item (device, ap, &dup_data, active_ap, active, connections, applet);
-		menu_list = g_list_append (menu_list, item);
+		nm_network_menu_item_best_strength (dup_data.found, nm_access_point_get_strength (ap), applet);
+		nm_network_menu_item_add_dupe (dup_data.found, ap);
+		return NULL;
 	}
 
-	if (active_ap == ap)
-		nm_network_menu_item_set_active (item, TRUE);
-	else
-		nm_network_menu_item_set_active (item, FALSE);
-
-	return menu_list;
+	return create_new_ap_item (device, ap, &dup_data, connections, applet);
 }
 
 static gint
-sort_wireless_networks (gconstpointer tmpa,
-                        gconstpointer tmpb)
+sort_by_name (gconstpointer tmpa, gconstpointer tmpb)
 {
-	NMAccessPoint * a = NM_ACCESS_POINT (tmpa);
-	NMAccessPoint * b = NM_ACCESS_POINT (tmpb);
-	const GByteArray * a_ssid;
-	const GByteArray * b_ssid;
-	NM80211Mode a_mode, b_mode;
+	NMNetworkMenuItem *a = NM_NETWORK_MENU_ITEM (tmpa);
+	NMNetworkMenuItem *b = NM_NETWORK_MENU_ITEM (tmpb);
+	const char *a_ssid, *b_ssid;
+	gboolean a_adhoc, b_adhoc;
 	int i;
 
 	if (a && !b)
 		return 1;
-	if (b && !a)
+	else if (!a && b)
 		return -1;
+	else if (!a && !b)
+		return 0;
+	else if (a == b)
+		return 0;
 
-	a_ssid = nm_access_point_get_ssid (a);
-	b_ssid = nm_access_point_get_ssid (b);
+	a_ssid = nm_network_menu_item_get_ssid (a);
+	b_ssid = nm_network_menu_item_get_ssid (b);
 
 	if (a_ssid && !b_ssid)
 		return 1;
@@ -626,79 +607,67 @@ sort_wireless_networks (gconstpointer tmpa,
 		return -1;
 
 	if (a_ssid && b_ssid) {
-		/* Can't use string compares because SSIDs are byte arrays and
-		 * may legally contain embedded NULLs.
-		 */
-		for (i = 0; i < MIN(a_ssid->len, b_ssid->len); i++) {
-			if (tolower(a_ssid->data[i]) > tolower(b_ssid->data[i]))
-				return 1;
-			else if (tolower(b_ssid->data[i]) > tolower(a_ssid->data[i]))
-				return -1;
-		}
-
-		if (a_ssid->len > b_ssid->len)
-			return 1;
-		if (b_ssid->len > a_ssid->len)
-			return -1;
+		i = g_ascii_strcasecmp (a_ssid, b_ssid);
+		if (i != 0)
+			return i;
 	}
 
-	a_mode = nm_access_point_get_mode (a);
-	b_mode = nm_access_point_get_mode (b);
-	if (a_mode != b_mode) {
-		if (a_mode == NM_802_11_MODE_INFRA)
-			return 1;
+	/* If the names are the same, sort infrastructure APs first */
+	a_adhoc = nm_network_menu_item_get_is_adhoc (a);
+	b_adhoc = nm_network_menu_item_get_is_adhoc (b);
+	if (a_adhoc && !b_adhoc)
+		return 1;
+	else if (!a_adhoc && b_adhoc)
 		return -1;
-	}
 
 	return 0;
 }
 
+/* Sort menu items for the top-level menu:
+ * 1) whether there's a saved connection or not
+ *    a) sort alphabetically within #1
+ * 2) encrypted without a saved connection
+ * 3) unencrypted without a saved connection
+ */
 static gint
-sort_ap_menu_item_by_name0 (gconstpointer a, gconstpointer b)
+sort_toplevel (gconstpointer tmpa, gconstpointer tmpb)
 {
-	if (a == b)
-		return 0;
-	if (!a && b)
-		return -1;
+	NMNetworkMenuItem *a = NM_NETWORK_MENU_ITEM (tmpa);
+	NMNetworkMenuItem *b = NM_NETWORK_MENU_ITEM (tmpb);
+	gboolean a_fave, b_fave;
+
 	if (a && !b)
 		return 1;
+	else if (!a && b)
+		return -1;
+	else if (!a && !b)
+		return 0;
+	else if (a == b)
+		return 0;
 
-	if (!NM_IS_NETWORK_MENU_ITEM (a) || !NM_IS_NETWORK_MENU_ITEM (b)) {
-		return GPOINTER_TO_UINT (a) < GPOINTER_TO_UINT (b) ? -1 : 1;
-	}
-
-	return g_ascii_strcasecmp (NM_NETWORK_MENU_ITEM (a)->sort_label, NM_NETWORK_MENU_ITEM (b)->sort_label);
-}
-
-static gint
-sort_ap_menu_item_by_fav_strength_name0 (gconstpointer a, gconstpointer b)
-{
-	gpointer favorite_a, favorite_b;
+	a_fave = nm_network_menu_item_get_has_connections (a);
+	b_fave = nm_network_menu_item_get_has_connections (b);
 
-	if (a == b)
-		return 0;
-	if (!a && b)
+	/* Items with a saved connection first */
+	if (a_fave && !b_fave)
 		return -1;
-	if (a && !b)
+	else if (!a_fave && b_fave)
 		return 1;
+	else if (!a_fave && !b_fave) {
+		gboolean a_enc = nm_network_menu_item_get_is_encrypted (a);
+		gboolean b_enc = nm_network_menu_item_get_is_encrypted (b);
 
-	if (!NM_IS_NETWORK_MENU_ITEM (a) || !NM_IS_NETWORK_MENU_ITEM (b)) {
-		return GPOINTER_TO_UINT (a) < GPOINTER_TO_UINT (b) ? -1 : 1;
+		/* If neither item has a saved connection, sort by encryption */
+		if (a_enc && !b_enc)
+			return -1;
+		else if (!a_enc && b_enc)
+			return 1;
 	}
-	favorite_a = g_object_get_data (G_OBJECT (a), "favorite");
-	favorite_b = g_object_get_data (G_OBJECT (b), "favorite");
-
-	if (GPOINTER_TO_UINT (favorite_a) < GPOINTER_TO_UINT (favorite_b))
-		return 1;
-	if (GPOINTER_TO_UINT (favorite_a) > GPOINTER_TO_UINT (favorite_b))
-		return -1;
-
-	if (NM_NETWORK_MENU_ITEM (a)->sort_strength < NM_NETWORK_MENU_ITEM (b)->sort_strength)
-		return 1;
-	if (NM_NETWORK_MENU_ITEM (a)->sort_strength > NM_NETWORK_MENU_ITEM (b)->sort_strength)
-		return -1;
 
-	return g_ascii_strcasecmp (NM_NETWORK_MENU_ITEM (a)->sort_label, NM_NETWORK_MENU_ITEM (b)->sort_label);
+	/* For all other cases (both have saved connections, both are encrypted, or
+	 * both are unencrypted) just sort by name.
+	 */
+	return sort_by_name (a, b);
 }
 
 static void
@@ -710,23 +679,18 @@ wireless_add_menu_item (NMDevice *device,
 {
 	NMDeviceWifi *wdev;
 	char *text;
-	GtkWidget *item;
 	const GPtrArray *aps;
 	int i;
 	NMAccessPoint *active_ap = NULL;
-	GSList *connections = NULL, *all, *sorted_aps = NULL, *iter;
+	GSList *connections = NULL, *all, *iter;
 	gboolean wireless_enabled = TRUE;
-	GList *menu_list = NULL;
-	GtkWidget *folded_menu_item;
-	GtkWidget *submenu;
+	GSList *menu_items = NULL;  /* All menu items we'll be adding */
+	NMNetworkMenuItem *item, *active_item = NULL;
+	GtkWidget *widget;
 
 	wdev = NM_DEVICE_WIFI (device);
 	aps = nm_device_wifi_get_access_points (wdev);
 
-	all = applet_get_all_connections (applet);
-	connections = utils_filter_connections_for_device (device, all);
-	g_slist_free (all);
-
 	if (n_devices > 1) {
 		char *desc;
 
@@ -742,62 +706,105 @@ wireless_add_menu_item (NMDevice *device,
 	} else
 		text = g_strdup (ngettext ("Wireless Network", "Wireless Networks", aps ? aps->len : 0));
 
-	item = applet_menu_item_create_device_item_helper (device, applet, text);
+	widget = applet_menu_item_create_device_item_helper (device, applet, text);
 	g_free (text);
 
-	gtk_widget_set_sensitive (item, FALSE);
-	gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
-	gtk_widget_show (item);
+	gtk_widget_set_sensitive (widget, FALSE);
+	gtk_menu_shell_append (GTK_MENU_SHELL (menu), widget);
+	gtk_widget_show (widget);
+
+	all = applet_get_all_connections (applet);
+	connections = utils_filter_connections_for_device (device, all);
+	g_slist_free (all);
 
-	active_ap = nm_device_wifi_get_active_access_point (wdev);
-	if (active_ap) {
-		menu_list = add_one_ap_menu_item (wdev, active_ap, connections, active_ap, active, menu_list, applet);
-		gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_list->data);
-		g_list_free (menu_list);
-		menu_list = NULL;
+	/* Add the active AP if we're connected to something and the device is available */
+	if (!nma_menu_device_check_unusable (device)) {
+		active_ap = nm_device_wifi_get_active_access_point (wdev);
+		if (active_ap) {
+			active_item = item = get_menu_item_for_ap (wdev, active_ap, connections, NULL, applet);
+			nm_network_menu_item_set_active (item, TRUE);
+			menu_items = g_slist_append (menu_items, item);
+
+			gtk_menu_shell_append (GTK_MENU_SHELL (menu), GTK_WIDGET (item));
+			gtk_widget_show_all (GTK_WIDGET (item));
+		}
 	}
 
 	/* Notify user of unmanaged or unavailable device */
 	wireless_enabled = nm_client_wireless_get_enabled (applet->nm_client);
-	item = nma_menu_device_get_menu_item (device, applet, wireless_enabled ? NULL : _("wireless is disabled"));
-	if (item) {
-		gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
-		gtk_widget_show (item);
+	widget = nma_menu_device_get_menu_item (device, applet, wireless_enabled ? NULL : _("wireless is disabled"));
+	if (widget) {
+		gtk_menu_shell_append (GTK_MENU_SHELL (menu), widget);
+		gtk_widget_show (widget);
 	}
 
-	if (!nma_menu_device_check_unusable (device)) {
+	/* If disabled or rfkilled or whatever, nothing left to do */
+	if (nma_menu_device_check_unusable (device))
+		goto out;
+
+	/* Create menu items for the rest of the APs */
+	for (i = 0; aps && (i < aps->len); i++) {
+		NMAccessPoint *ap = g_ptr_array_index (aps, i);
+
+		item = get_menu_item_for_ap (wdev, ap, connections, menu_items, applet);
+		if (item)
+			menu_items = g_slist_append (menu_items, item);
+	}
+
+	/* Now remove the active AP item from the list, as we've already dealt with
+	 * it.  (Needed it when creating menu items for the rest of the APs though
+	 * to ensure duplicate APs are handled correctly)
+	 */
+	if (active_item)
+		menu_items = g_slist_remove (menu_items, active_item);
+
+	/* Sort all the rest of the menu items for the top-level menu */
+	menu_items = g_slist_sort (menu_items, sort_toplevel);
+
+	if (g_slist_length (menu_items)) {
+		GSList *submenu_items = NULL;
+		guint32 num_for_toplevel = 5;
+
 		applet_menu_item_add_complex_separator_helper (menu, applet, _("Available"), -1);
 
-		/* Add all networks in our network list to the menu */
-		for (i = 0; aps && (i < aps->len); i++)
-			sorted_aps = g_slist_append (sorted_aps, g_ptr_array_index (aps, i));
-
-		sorted_aps = g_slist_sort (sorted_aps, sort_wireless_networks);
-		for (iter = sorted_aps; iter; iter = g_slist_next (iter)) {
-			if (active_ap != NM_ACCESS_POINT (iter->data)) {
-				menu_list = add_one_ap_menu_item (wdev,
-				                                  NM_ACCESS_POINT (iter->data),
-				                                  connections,
-				                                  active_ap,
-				                                  active,
-				                                  menu_list,
-				                                  applet);
-			}
+		if (g_slist_length (menu_items) == (num_for_toplevel + 1))
+			num_for_toplevel++;
+
+		/* Add the first 5 APs (or 6 if there are only 6 total) from the sorted
+		 * toplevel list.
+		 */
+		for (iter = menu_items; iter && num_for_toplevel; iter = g_slist_next (iter)) {
+			gtk_menu_shell_append (GTK_MENU_SHELL (menu), GTK_WIDGET (iter->data));
+			gtk_widget_show_all (GTK_WIDGET (iter->data));
+			num_for_toplevel--;
+			submenu_items = iter->next;
 		}
 
-		folded_menu_item = gtk_menu_item_new_with_mnemonic (_("More networks..."));
-		submenu = gtk_menu_new ();
-		gtk_menu_item_set_submenu (GTK_MENU_ITEM (folded_menu_item), submenu);
-		applet_menu_add_items_top_and_fold_sorted_helper (GTK_MENU (menu),
-		                                                  menu_list,
-		                                                  5,
-		                                                  GTK_WIDGET (folded_menu_item),
-		                                                  sort_ap_menu_item_by_fav_strength_name0,
-       	                                                  sort_ap_menu_item_by_name0);
-		g_list_free (menu_list);
-		g_slist_free (sorted_aps);
+		/* If there are any submenu items, make a submenu for those */
+		if (submenu_items) {
+			GtkWidget *subitem, *submenu;
+			GSList *sorted_subitems;
+
+			subitem = gtk_menu_item_new_with_mnemonic (_("More networks..."));
+			submenu = gtk_menu_new ();
+			gtk_menu_item_set_submenu (GTK_MENU_ITEM (subitem), submenu);
+
+			/* Sort the subitems alphabetically */
+			sorted_subitems = g_slist_copy (submenu_items);
+			sorted_subitems = g_slist_sort (sorted_subitems, sort_by_name);
+
+			/* And add the rest to the submenu */
+			for (iter = sorted_subitems; iter; iter = g_slist_next (iter))
+				gtk_menu_shell_append (GTK_MENU_SHELL (submenu), GTK_WIDGET (iter->data));
+			g_slist_free (sorted_subitems);
+
+			gtk_menu_shell_append (GTK_MENU_SHELL (menu), subitem);
+			gtk_widget_show_all (subitem);
+		}
 	}
 
+out:
+	g_slist_free (menu_items);
 	g_slist_free (connections);
 }
 
diff --git a/src/applet.c b/src/applet.c
index fbbcef9..ca8d7f4 100644
--- a/src/applet.c
+++ b/src/applet.c
@@ -448,66 +448,6 @@ applet_menu_item_add_complex_separator_helper (GtkWidget *menu,
 	return;
 }
 
-void
-applet_menu_add_items_top_and_fold_sorted_helper (GtkMenu *menu,
-                                                  GList *items,
-                                                  guint top_count,
-                                                  GtkWidget *submenu_item,
-                                                  GCompareFunc prio_cmp_func,
-                                                  GCompareFunc generic_cmp_func)
-{
-	GList *iter = items;
-	GList *clone_top = NULL;
-	GList *clone_top_filtered = NULL;
-	GList *clone_folded = NULL;
-	GtkWidget *submenu;
-	int i;
-
-	g_assert (menu);
-	g_assert (top_count > 0);
-	g_assert (submenu_item);
-	g_assert (prio_cmp_func);
-	g_assert (generic_cmp_func);
-
-	submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (submenu_item));
-	g_assert (submenu_item);
-
-	while (iter) {
-		clone_top = g_list_append (clone_top, iter->data);
-		clone_folded = g_list_append (clone_folded, iter->data);
-		iter = iter->next;
-	}
-
-	clone_top = g_list_sort (clone_top, prio_cmp_func);
-	clone_folded = g_list_sort (clone_folded, generic_cmp_func);
-
-	iter = clone_top;
-	for (i = 0; !!iter && i < top_count; i++, iter = iter->next) {
-		clone_folded = g_list_remove (clone_folded, iter->data);
-		clone_top_filtered = g_list_append (clone_top_filtered, iter->data);
-	}
-
-
-	clone_top_filtered = g_list_sort (clone_top_filtered, generic_cmp_func);
-	iter = clone_top_filtered;
-	while (iter) {
-		gtk_menu_shell_append (GTK_MENU_SHELL (menu), iter->data);
-		iter = iter->next;
-	}
-
-	iter = clone_folded;
-	if (iter)
-		gtk_menu_shell_append (GTK_MENU_SHELL (menu), submenu_item);
-	while (iter) {
-		gtk_menu_shell_append (GTK_MENU_SHELL (submenu), iter->data);
-		iter = iter->next;
-	}
-
-	g_list_free(clone_top);
-	g_list_free(clone_top_filtered);
-	g_list_free(clone_folded);
-}
-
 #define TITLE_TEXT_R ((double) 0x5e / 255.0 )
 #define TITLE_TEXT_G ((double) 0x5e / 255.0 )
 #define TITLE_TEXT_B ((double) 0x5e / 255.0 )
@@ -616,7 +556,7 @@ menu_title_item_expose (GtkWidget *widget, GdkEventExpose *event)
 }
 
 
-GtkWidget*
+GtkWidget *
 applet_menu_item_create_device_item_helper (NMDevice *device,
                                             NMApplet *applet,
                                             const gchar *text)
@@ -2794,9 +2734,6 @@ setup_widgets (NMApplet *applet)
 	applet->context_menu = nma_context_menu_create (applet);
 	if (!applet->context_menu)
 		return FALSE;
-	applet->encryption_size_group = gtk_size_group_new (GTK_SIZE_GROUP_BOTH);
-	if (!applet->encryption_size_group)
-		return FALSE;
 
 	return TRUE;
 }
@@ -2986,9 +2923,6 @@ static void finalize (GObject *object)
 	if (applet->gconf_client)
 		g_object_unref (applet->gconf_client);
 
-	if (applet->encryption_size_group)
-		g_object_unref (applet->encryption_size_group);
-
 	if (applet->status_icon)
 		g_object_unref (applet->status_icon);
 
diff --git a/src/applet.h b/src/applet.h
index 9899754..8386fe8 100644
--- a/src/applet.h
+++ b/src/applet.h
@@ -133,7 +133,6 @@ typedef struct
 	int				size;
 
 	GtkWidget *		menu;
-	GtkSizeGroup *	encryption_size_group;
 	char *          tip;
 
 	GtkWidget *		context_menu;
@@ -229,12 +228,6 @@ void applet_menu_item_add_complex_separator_helper (GtkWidget *menu,
                                                     const gchar* label,
                                                     int pos);
 
-void applet_menu_add_items_top_and_fold_sorted_helper (GtkMenu *menu,
-                                                       GList *items,
-                                                       guint top_count,
-                                                       GtkWidget *submenu_item,
-                                                       GCompareFunc prio_cmp_func,
-                                                       GCompareFunc generic_cmp_func);
 GtkWidget*
 applet_menu_item_create_device_item_helper (NMDevice *device,
                                             NMApplet *applet,



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