[network-manager-applet] core: implement device disconnect feature (UI part)



commit ab4a16b58105b0b1a9a644d8c0eaf86e69df8fa6
Author: Alexander Sack <asac ubuntu com>
Date:   Fri Sep 18 09:07:59 2009 -0700

    core: implement device disconnect feature (UI part)
    
    refactor menu production code for all device classes
    to support a special "device" menu entry that is used
    to display our previous error labels "disconnected", "not ready", etc.
    We use this mechanism to return a sensitive "Disconnect" menu entry.
    Clicking the "Disconnect" menu entry calls the new libnm-glib
    nm_device_disconnect function.
    
    Since this is a universal feature working for all device classes, we drop the
    gsm/cdma specific code that added a disconnect entry for those device classes
    in the past.
    
    (cleanups and async conversion by dcbw)

 src/applet-device-bt.c    |    7 ++-
 src/applet-device-cdma.c  |   59 +++-------------------------
 src/applet-device-gsm.c   |   59 +++-------------------------
 src/applet-device-wifi.c  |   32 +++++++++------
 src/applet-device-wired.c |   14 +++---
 src/applet.c              |   94 ++++++++++++++++++++++++++++++++++++++++++--
 src/applet.h              |    8 +++-
 7 files changed, 142 insertions(+), 131 deletions(-)
---
diff --git a/src/applet-device-bt.c b/src/applet-device-bt.c
index b614052..47287fd 100644
--- a/src/applet-device-bt.c
+++ b/src/applet-device-bt.c
@@ -154,11 +154,14 @@ bt_add_menu_item (NMDevice *device,
 	gtk_widget_show (item);
 
 	/* Notify user of unmanaged or unavailable device */
-	item = nma_menu_device_check_unusable (device, NULL);
+	item = nma_menu_device_get_menu_item (device, applet, NULL);
 	if (item) {
 		gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
 		gtk_widget_show (item);
-	} else {
+	}
+
+	if (!nma_menu_device_check_unusable (device)) {
+		/* Add menu items for existing bluetooth connections for this device */
 		if (g_slist_length (connections))
 			add_connection_items (device, connections, carrier, active, menu, applet);
 	}
diff --git a/src/applet-device-cdma.c b/src/applet-device-cdma.c
index 73feb10..cf73890 100644
--- a/src/applet-device-cdma.c
+++ b/src/applet-device-cdma.c
@@ -226,50 +226,6 @@ add_default_connection_item (NMDevice *device,
 }
 
 static void
-cdma_menu_item_deactivate (GtkMenuItem *item, gpointer user_data)
-{
-	CdmaMenuItemInfo *info = (CdmaMenuItemInfo *) user_data;
-	NMActiveConnection *active = NULL;
-
-	applet_find_active_connection_for_device (info->device, info->applet, &active);
-	if (active)
-		nm_client_deactivate_connection (info->applet->nm_client, active);
-	else
-		g_warning ("%s: couldn't find active connection to deactive", __func__);
-}
-
-static void
-add_disconnect_item (NMDevice *device,
-                     GtkWidget *menu,
-                     NMApplet *applet)
-{
-	NMDeviceState state;
-	GtkWidget *item;
-	CdmaMenuItemInfo *info;
-
-	state = nm_device_get_state (device);
-	if (   state == NM_DEVICE_STATE_UNKNOWN
-	    || state == NM_DEVICE_STATE_UNMANAGED
-	    || state == NM_DEVICE_STATE_UNAVAILABLE
-	    || state == NM_DEVICE_STATE_DISCONNECTED
-	    || state == NM_DEVICE_STATE_FAILED)
-		return;
-
-	item = gtk_menu_item_new_with_label (_("Disconnect"));
-
-	info = g_slice_new0 (CdmaMenuItemInfo);
-	info->applet = applet;
-	info->device = g_object_ref (G_OBJECT (device));
-
-	g_signal_connect_data (item, "activate",
-	                       G_CALLBACK (cdma_menu_item_deactivate),
-	                       info,
-	                       (GClosureNotify) cdma_menu_item_info_destroy, 0);
-
-	gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
-}
-
-static void
 cdma_add_menu_item (NMDevice *device,
                     guint32 n_devices,
                     NMConnection *active,
@@ -313,20 +269,19 @@ cdma_add_menu_item (NMDevice *device,
 	gtk_widget_show (item);
 
 	/* Notify user of unmanaged or unavailable device */
-	item = nma_menu_device_check_unusable (device, NULL);
+	item = nma_menu_device_get_menu_item (device, applet, NULL);
 	if (item) {
 		gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
 		gtk_widget_show (item);
-		goto out;
 	}
 
-	if (g_slist_length (connections))
-		add_connection_items (device, connections, active, menu, applet);
-	else
-		add_default_connection_item (device, menu, applet);
-	add_disconnect_item (device, menu, applet);
+	if (!nma_menu_device_check_unusable (device)) {
+		if (g_slist_length (connections))
+			add_connection_items (device, connections, active, menu, applet);
+		else
+			add_default_connection_item (device, menu, applet);
+	}
 
-out:
 	g_slist_free (connections);
 }
 
diff --git a/src/applet-device-gsm.c b/src/applet-device-gsm.c
index e69385c..90bf31f 100644
--- a/src/applet-device-gsm.c
+++ b/src/applet-device-gsm.c
@@ -228,50 +228,6 @@ add_default_connection_item (NMDevice *device,
 }
 
 static void
-gsm_menu_item_deactivate (GtkMenuItem *item, gpointer user_data)
-{
-	GSMMenuItemInfo *info = (GSMMenuItemInfo *) user_data;
-	NMActiveConnection *active = NULL;
-
-	applet_find_active_connection_for_device (info->device, info->applet, &active);
-	if (active)
-		nm_client_deactivate_connection (info->applet->nm_client, active);
-	else
-		g_warning ("%s: couldn't find active connection to deactive", __func__);
-}
-
-static void
-add_disconnect_item (NMDevice *device,
-                     GtkWidget *menu,
-                     NMApplet *applet)
-{
-	NMDeviceState state;
-	GtkWidget *item;
-	GSMMenuItemInfo *info;
-
-	state = nm_device_get_state (device);
-	if (   state == NM_DEVICE_STATE_UNKNOWN
-	    || state == NM_DEVICE_STATE_UNMANAGED
-	    || state == NM_DEVICE_STATE_UNAVAILABLE
-	    || state == NM_DEVICE_STATE_DISCONNECTED
-	    || state == NM_DEVICE_STATE_FAILED)
-		return;
-
-	item = gtk_menu_item_new_with_label (_("Disconnect"));
-
-	info = g_slice_new0 (GSMMenuItemInfo);
-	info->applet = applet;
-	info->device = g_object_ref (G_OBJECT (device));
-
-	g_signal_connect_data (item, "activate",
-	                       G_CALLBACK (gsm_menu_item_deactivate),
-	                       info,
-	                       (GClosureNotify) gsm_menu_item_info_destroy, 0);
-
-	gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
-}
-
-static void
 gsm_add_menu_item (NMDevice *device,
                    guint32 n_devices,
                    NMConnection *active,
@@ -315,20 +271,19 @@ gsm_add_menu_item (NMDevice *device,
 	gtk_widget_show (item);
 
 	/* Notify user of unmanaged or unavailable device */
-	item = nma_menu_device_check_unusable (device, NULL);
+	item = nma_menu_device_get_menu_item (device, applet, NULL);
 	if (item) {
 		gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
 		gtk_widget_show (item);
-		goto out;
 	}
 
-	if (g_slist_length (connections))
-		add_connection_items (device, connections, active, menu, applet);
-	else
-		add_default_connection_item (device, menu, applet);
-	add_disconnect_item (device, menu, applet);
+	if (!nma_menu_device_check_unusable (device)) {
+		if (g_slist_length (connections))
+			add_connection_items (device, connections, active, menu, applet);
+		else
+			add_default_connection_item (device, menu, applet);
+	}
 
-out:
 	g_slist_free (connections);
 }
 
diff --git a/src/applet-device-wifi.c b/src/applet-device-wifi.c
index 180337f..525f74d 100644
--- a/src/applet-device-wifi.c
+++ b/src/applet-device-wifi.c
@@ -713,26 +713,34 @@ wireless_add_menu_item (NMDevice *device,
 
 	/* Notify user of unmanaged or unavailable device */
 	wireless_enabled = nm_client_wireless_get_enabled (applet->nm_client);
-	item = nma_menu_device_check_unusable (device, wireless_enabled ? NULL : _("wireless is disabled"));
+	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);
-		goto out;
 	}
 
-	active_ap = nm_device_wifi_get_active_access_point (wdev);
-
-	/* 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));
+	if (!nma_menu_device_check_unusable (device)) {
+		active_ap = nm_device_wifi_get_active_access_point (wdev);
+
+		/* 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)) {
+			add_one_ap_menu_item (wdev,
+			                      NM_ACCESS_POINT (iter->data),
+			                      connections,
+			                      active_ap,
+			                      active,
+			                      menu,
+			                      applet);
+		}
 
-	sorted_aps = g_slist_sort (sorted_aps, sort_wireless_networks);
-	for (iter = sorted_aps; iter; iter = g_slist_next (iter))
-		add_one_ap_menu_item (wdev, NM_ACCESS_POINT (iter->data), connections, active_ap, active, menu, applet);
+		g_slist_free (sorted_aps);
+	}
 
-out:
 	g_slist_free (connections);
-	g_slist_free (sorted_aps);
 }
 
 static gboolean
diff --git a/src/applet-device-wired.c b/src/applet-device-wired.c
index dc24051..e12f99f 100644
--- a/src/applet-device-wired.c
+++ b/src/applet-device-wired.c
@@ -226,19 +226,19 @@ wired_add_menu_item (NMDevice *device,
 	gtk_widget_show (item);
 
 	/* Notify user of unmanaged or unavailable device */
-	item = nma_menu_device_check_unusable (device, carrier ? NULL : _("disconnected"));
+	item = nma_menu_device_get_menu_item (device, applet, carrier ? NULL : _("disconnected"));
 	if (item) {
 		gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
 		gtk_widget_show (item);
-		goto out;
 	}
 
-	if (g_slist_length (connections))
-		add_connection_items (device, connections, carrier, active, menu, applet);
-	else
-		add_default_connection_item (device, carrier, menu, applet);
+	if (!nma_menu_device_check_unusable (device)) {
+		if (g_slist_length (connections))
+			add_connection_items (device, connections, carrier, active, menu, applet);
+		else
+			add_default_connection_item (device, carrier, menu, applet);
+	}
 
-out:
 	g_slist_free (connections);
 }
 
diff --git a/src/applet.c b/src/applet.c
index 160af59..13bee6a 100644
--- a/src/applet.c
+++ b/src/applet.c
@@ -358,6 +358,27 @@ applet_menu_item_activate_helper_part2 (NMConnection *connection,
 	applet_item_activate_info_destroy (info);
 }
 
+static void
+disconnect_cb (NMDevice *device, GError *error, gpointer user_data)
+{
+	if (error) {
+		g_warning ("%s: device disconnect failed: (%d) %s",
+		           __func__,
+		           error ? error->code : -1,
+		           error && error->message ? error->message : "(unknown)");
+	}
+}
+
+void
+applet_menu_item_disconnect_helper (NMDevice *device,
+                                    NMApplet *applet)
+{
+	g_return_if_fail (NM_IS_DEVICE (device));
+
+	nm_device_disconnect (device, disconnect_cb, NULL);
+}
+
+
 void
 applet_menu_item_activate_helper (NMDevice *device,
                                   NMConnection *connection,
@@ -1061,9 +1082,50 @@ applet_find_active_connection_for_device (NMDevice *device,
 	return connection;
 }
 
+gboolean
+nma_menu_device_check_unusable (NMDevice *device)
+{
+	switch (nm_device_get_state (device)) {
+	case NM_DEVICE_STATE_UNKNOWN:
+	case NM_DEVICE_STATE_UNAVAILABLE:
+	case NM_DEVICE_STATE_UNMANAGED:
+		return TRUE;
+	default:
+		break;
+	}
+	return FALSE;
+}
+
+
+struct AppletDeviceMenuInfo {
+	NMDevice *device;
+	NMApplet *applet;
+};
+
+static void
+applet_device_info_destroy (struct AppletDeviceMenuInfo *info)
+{
+	g_return_if_fail (info != NULL);
+
+	if (info->device)
+		g_object_unref (info->device);
+	memset (info, 0, sizeof (struct AppletDeviceMenuInfo));
+	g_free (info);
+}
+
+static void
+applet_device_disconnect_db (GtkMenuItem *item, gpointer user_data)
+{
+	struct AppletDeviceMenuInfo *info = user_data;
+
+	applet_menu_item_disconnect_helper (info->device,
+	                                    info->applet);
+}
+
 GtkWidget *
-nma_menu_device_check_unusable (NMDevice *device,
-                                const char *unavailable_msg)
+nma_menu_device_get_menu_item (NMDevice *device,
+                               NMApplet *applet,
+                               const char *unavailable_msg)
 {
 	GtkWidget *item = NULL;
 	gboolean managed = TRUE;
@@ -1075,20 +1137,42 @@ nma_menu_device_check_unusable (NMDevice *device,
 	case NM_DEVICE_STATE_UNKNOWN:
 	case NM_DEVICE_STATE_UNAVAILABLE:
 		item = gtk_menu_item_new_with_label (unavailable_msg);
+		gtk_widget_set_sensitive (item, FALSE);
+		break;
+	case NM_DEVICE_STATE_DISCONNECTED:
+		unavailable_msg = _("disconnected");
+		item = gtk_menu_item_new_with_label (unavailable_msg);
+		gtk_widget_set_sensitive (item, FALSE);
 		break;
 	case NM_DEVICE_STATE_UNMANAGED:
 		managed = FALSE;
 		break;
+	case NM_DEVICE_STATE_PREPARE:
+	case NM_DEVICE_STATE_CONFIG:
+	case NM_DEVICE_STATE_NEED_AUTH:
+	case NM_DEVICE_STATE_IP_CONFIG:
+	case NM_DEVICE_STATE_ACTIVATED:
+	{
+		struct AppletDeviceMenuInfo *info = g_new0 (struct AppletDeviceMenuInfo, 1);
+		info->device = g_object_ref (device);
+		info->applet = applet;
+		item = gtk_menu_item_new_with_label (_("  Disconnect"));
+		g_signal_connect_data (item, "activate",
+		                       G_CALLBACK (applet_device_disconnect_db),
+		                       info,
+		                       (GClosureNotify) applet_device_info_destroy, 0);
+		gtk_widget_set_sensitive (item, TRUE);
+		break;
+	}
 	default:
 		managed = nm_device_get_managed (device);
 		break;
 	}
 
-	if (!managed)
+	if (!managed) {
 		item = gtk_menu_item_new_with_label (_("device not managed"));
-
-	if (item)
 		gtk_widget_set_sensitive (item, FALSE);
+	}
 
 	return item;
 }
diff --git a/src/applet.h b/src/applet.h
index de4ddfc..d38e59a 100644
--- a/src/applet.h
+++ b/src/applet.h
@@ -204,7 +204,10 @@ NMSettingsInterface *applet_get_settings (NMApplet *applet);
 
 GSList *applet_get_all_connections (NMApplet *applet);
 
-GtkWidget *nma_menu_device_check_unusable (NMDevice *device,
+gboolean nma_menu_device_check_unusable (NMDevice *device);
+
+GtkWidget * nma_menu_device_get_menu_item (NMDevice *device,
+                                           NMApplet *applet,
                                            const char *unavailable_msg);
 
 void applet_menu_item_activate_helper (NMDevice *device,
@@ -213,6 +216,9 @@ void applet_menu_item_activate_helper (NMDevice *device,
                                        NMApplet *applet,
                                        gpointer dclass_data);
 
+void applet_menu_item_disconnect_helper (NMDevice *device,
+                                         NMApplet *applet);
+
 NMSettingsConnectionInterface *applet_get_exported_connection_for_device (NMDevice *device, NMApplet *applet);
 
 void applet_do_notify (NMApplet *applet,



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