[network-manager-applet] libnm-gtk: expose APIs for user-displayable descriptions



commit 209090cc82665a9563723ffa5a9756fde97a84e3
Author: Dan Winship <danw gnome org>
Date:   Tue Oct 2 09:42:27 2012 -0400

    libnm-gtk: expose APIs for user-displayable descriptions
    
    Expose the former utils_get_device_description() as
    nma_utils_get_device_description() and add several other display-name
    utilities, including nma_utils_disambiguate_device_names() for the
    control center.

 configure.ac                     |    4 +
 po/POTFILES.in                   |    1 +
 src/applet-device-bt.c           |   10 +-
 src/applet-device-cdma.c         |    9 +-
 src/applet-device-ethernet.c     |    9 +-
 src/applet-device-gsm.c          |   11 +-
 src/applet-device-wifi.c         |    9 +-
 src/applet-device-wimax.c        |   10 +-
 src/applet.c                     |   14 +-
 src/libnm-gtk/Makefile.am        |    8 +-
 src/libnm-gtk/nm-mobile-wizard.c |    6 +-
 src/libnm-gtk/nm-ui-utils.c      |  499 ++++++++++++++++++++++++++++++++++++++
 src/libnm-gtk/nm-ui-utils.h      |   40 +++
 src/libnm-gtk/nm-wifi-dialog.c   |   10 +-
 src/utils/utils.c                |  151 ------------
 src/utils/utils.h                |    2 -
 16 files changed, 580 insertions(+), 213 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index f18b36b..bd9c461 100644
--- a/configure.ac
+++ b/configure.ac
@@ -202,6 +202,10 @@ esac
 
 AM_CONDITIONAL(HAVE_GBT, test x"$have_gbt" = "xyes")
 
+PKG_CHECK_MODULES(GUDEV, gudev-1.0 >= 147)
+AC_SUBST(GUDEV_CFLAGS)
+AC_SUBST(GUDEV_LIBS)
+
 GLIB_CONFIG_NMA
 
 dnl
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 723758c..47b52e2 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -57,6 +57,7 @@ src/gnome-bluetooth/nma-bt-device.c
 [type: gettext/glade]src/info.ui
 src/libnm-gtk/nm-mobile-wizard.c
 src/libnm-gtk/nm-wifi-dialog.c
+src/libnm-gtk/nm-ui-utils.c
 [type: gettext/glade]src/libnm-gtk/wifi.ui
 src/main.c
 src/mb-menu-item.c
diff --git a/src/applet-device-bt.c b/src/applet-device-bt.c
index 6ff43af..5a17846 100644
--- a/src/applet-device-bt.c
+++ b/src/applet-device-bt.c
@@ -39,8 +39,8 @@
 
 #include "applet.h"
 #include "applet-device-bt.h"
-#include "utils.h"
 #include "applet-dialogs.h"
+#include "nm-ui-utils.h"
 
 typedef struct {
 	NMApplet *applet;
@@ -144,12 +144,8 @@ bt_add_menu_item (NMDevice *device,
 	g_slist_free (all);
 
 	text = nm_device_bt_get_name (NM_DEVICE_BT (device));
-	if (!text) {
-		text = utils_get_device_description (device);
-		if (!text)
-			text = nm_device_get_iface (device);
-		g_assert (text);
-	}
+	if (!text)
+		text = nma_utils_get_device_description (device);
 
 	item = applet_menu_item_create_device_item_helper (device, applet, text);
 
diff --git a/src/applet-device-cdma.c b/src/applet-device-cdma.c
index 632be34..41510bc 100644
--- a/src/applet-device-cdma.c
+++ b/src/applet-device-cdma.c
@@ -44,6 +44,7 @@
 #include "nma-marshal.h"
 #include "nmn-mobile-providers.h"
 #include "mb-menu-item.h"
+#include "nm-ui-utils.h"
 
 typedef struct {
 	NMApplet *applet;
@@ -332,13 +333,9 @@ cdma_add_menu_item (NMDevice *device,
 	g_slist_free (all);
 
 	if (n_devices > 1) {
-		char *desc;
-
-		desc = (char *) utils_get_device_description (device);
-		if (!desc)
-			desc = (char *) nm_device_get_iface (device);
-		g_assert (desc);
+		const char *desc;
 
+		desc = nma_utils_get_device_description (device);
 		text = g_strdup_printf (_("Mobile Broadband (%s)"), desc);
 	} else {
 		text = g_strdup (_("Mobile Broadband"));
diff --git a/src/applet-device-ethernet.c b/src/applet-device-ethernet.c
index 5e58764..6e63dcb 100644
--- a/src/applet-device-ethernet.c
+++ b/src/applet-device-ethernet.c
@@ -39,7 +39,7 @@
 #include "applet.h"
 #include "applet-device-ethernet.h"
 #include "ethernet-dialog.h"
-#include "utils.h"
+#include "nm-ui-utils.h"
 
 typedef struct {
 	NMApplet *applet;
@@ -194,12 +194,9 @@ ethernet_add_menu_item (NMDevice *device,
 	g_slist_free (all);
 
 	if (n_devices > 1) {
-		char *desc = NULL;
+		const char *desc;
 
-		desc = (char *) utils_get_device_description (device);
-		if (!desc)
-			desc = (char *) nm_device_get_iface (device);
-		g_assert (desc);
+		desc = nma_utils_get_device_description (device);
 
 		if (g_slist_length (connections) > 1)
 			text = g_strdup_printf (_("Ethernet Networks (%s)"), desc);
diff --git a/src/applet-device-gsm.c b/src/applet-device-gsm.c
index 27e7a04..3166543 100644
--- a/src/applet-device-gsm.c
+++ b/src/applet-device-gsm.c
@@ -47,6 +47,7 @@
 #include "mb-menu-item.h"
 #include "nma-marshal.h"
 #include "nmn-mobile-providers.h"
+#include "nm-ui-utils.h"
 
 typedef enum {
     MM_MODEM_GSM_ACCESS_TECH_UNKNOWN     = 0,
@@ -386,13 +387,9 @@ gsm_add_menu_item (NMDevice *device,
 	g_slist_free (all);
 
 	if (n_devices > 1) {
-		char *desc;
-
-		desc = (char *) utils_get_device_description (device);
-		if (!desc)
-			desc = (char *) nm_device_get_iface (device);
-		g_assert (desc);
+		const char *desc;
 
+		desc = nma_utils_get_device_description (device);
 		text = g_strdup_printf (_("Mobile Broadband (%s)"), desc);
 	} else {
 		text = g_strdup (_("Mobile Broadband"));
@@ -987,7 +984,7 @@ unlock_dialog_new (NMDevice *device, GsmDeviceInfo *info)
 		return;
 
 	/* Figure out the dialog text based on the required unlock code */
-	device_desc = utils_get_device_description (device);
+	device_desc = nma_utils_get_device_description (device);
 	if (!strcmp (info->unlock_required, "sim-pin")) {
 		title = _("SIM PIN unlock required");
 		header = _("SIM PIN Unlock Required");
diff --git a/src/applet-device-wifi.c b/src/applet-device-wifi.c
index dbf59f6..bd02592 100644
--- a/src/applet-device-wifi.c
+++ b/src/applet-device-wifi.c
@@ -46,6 +46,7 @@
 #include "ap-menu-item.h"
 #include "utils.h"
 #include "nm-wifi-dialog.h"
+#include "nm-ui-utils.h"
 
 #define ACTIVE_AP_TAG "active-ap"
 
@@ -779,13 +780,9 @@ wifi_add_menu_item (NMDevice *device,
 	aps = nm_device_wifi_get_access_points (wdev);
 
 	if (n_devices > 1) {
-		char *desc;
-
-		desc = (char *) utils_get_device_description (device);
-		if (!desc)
-			desc = (char *) nm_device_get_iface (device);
-		g_assert (desc);
+		const char *desc;
 
+		desc = nma_utils_get_device_description (device);
 		if (aps && aps->len > 1)
 			text = g_strdup_printf (_("Wi-Fi Networks (%s)"), desc);
 		else
diff --git a/src/applet-device-wimax.c b/src/applet-device-wimax.c
index a82b974..a870c48 100644
--- a/src/applet-device-wimax.c
+++ b/src/applet-device-wimax.c
@@ -35,10 +35,10 @@
 
 #include "applet.h"
 #include "applet-device-wimax.h"
-#include "utils.h"
 #include "applet-dialogs.h"
 #include "nma-marshal.h"
 #include "mb-menu-item.h"
+#include "nm-ui-utils.h"
 
 #define ACTIVE_NSP_TAG "active-nsp"
 
@@ -221,13 +221,9 @@ wimax_add_menu_item (NMDevice *device,
 	nsps = nm_device_wimax_get_nsps (wimax);
 
 	if (n_devices > 1) {
-		char *desc;
-
-		desc = (char *) utils_get_device_description (device);
-		if (!desc)
-			desc = (char *) nm_device_get_iface (device);
-		g_assert (desc);
+		const char *desc;
 
+		desc = nma_utils_get_device_description (device);
 		text = g_strdup_printf (_("WiMAX Mobile Broadband (%s)"), desc);
 	} else {
 		text = g_strdup (_("WiMAX Mobile Broadband"));
diff --git a/src/applet.c b/src/applet.c
index 819a307..21b549f 100644
--- a/src/applet.c
+++ b/src/applet.c
@@ -78,6 +78,7 @@
 #include "applet-vpn-request.h"
 #include "utils.h"
 #include "shell-watcher.h"
+#include "nm-ui-utils.h"
 
 #define NOTIFY_CAPS_ACTIONS_KEY "actions"
 
@@ -1374,16 +1375,11 @@ sort_devices (gconstpointer a, gconstpointer b)
 	GType bb_type = G_OBJECT_TYPE (G_OBJECT (bb));
 
 	if (aa_type == bb_type) {
-		char *aa_desc = NULL;
-		char *bb_desc = NULL;
+		const char *aa_desc = NULL;
+		const char *bb_desc = NULL;
 
-		aa_desc = (char *) utils_get_device_description (aa);
-		if (!aa_desc)
-			aa_desc = (char *) nm_device_get_iface (aa);
-
-		bb_desc = (char *) utils_get_device_description (bb);
-		if (!bb_desc)
-			bb_desc = (char *) nm_device_get_iface (bb);
+		aa_desc = nma_utils_get_device_description (aa);
+		bb_desc = nma_utils_get_device_description (bb);
 
 		return g_strcmp0 (aa_desc, bb_desc);
 	}
diff --git a/src/libnm-gtk/Makefile.am b/src/libnm-gtk/Makefile.am
index abc1f8a..74491a0 100644
--- a/src/libnm-gtk/Makefile.am
+++ b/src/libnm-gtk/Makefile.am
@@ -6,20 +6,23 @@ libnmgtkdir = $(includedir)/libnm-gtk
 libnmgtk_HEADERS = \
 	nm-wifi-dialog.h \
 	nm-wireless-dialog.h \
-	nm-mobile-wizard.h
+	nm-mobile-wizard.h \
+	nm-ui-utils.h
 
 lib_LTLIBRARIES = libnm-gtk.la
 
 libnm_gtk_la_SOURCES = \
 	nm-wifi-dialog.c \
 	nm-wireless-dialog.c \
-	nm-mobile-wizard.c
+	nm-mobile-wizard.c \
+	nm-ui-utils.c
 
 libnm_gtk_la_CFLAGS = \
 	$(GTK_CFLAGS) \
 	$(NMA_CFLAGS) \
 	$(DBUS_CFLAGS) \
 	$(GNOME_KEYRING_CFLAGS) \
+	$(GUDEV_CFLAGS) \
 	-DICONDIR=\""$(datadir)/icons"\" \
 	-DUIDIR=\""$(uidir)"\" \
 	-DBINDIR=\""$(bindir)"\" \
@@ -37,6 +40,7 @@ libnm_gtk_la_LIBADD = \
 	$(GTK_LIBS) \
 	$(NMA_LIBS) \
 	$(GNOME_KEYRING_LIBS) \
+	$(GUDEV_LIBS) \
 	$(top_builddir)/src/marshallers/libmarshallers.la \
 	$(top_builddir)/src/wireless-security/libwireless-security.la
 
diff --git a/src/libnm-gtk/nm-mobile-wizard.c b/src/libnm-gtk/nm-mobile-wizard.c
index 14d30bb..b9ce9d5 100644
--- a/src/libnm-gtk/nm-mobile-wizard.c
+++ b/src/libnm-gtk/nm-mobile-wizard.c
@@ -38,7 +38,7 @@
 
 #include "nm-mobile-wizard.h"
 #include "nmn-mobile-providers.h"
-#include "utils.h"
+#include "nm-ui-utils.h"
 
 #define DEVICE_TAG "device"
 #define TYPE_TAG "setting-type"
@@ -1201,7 +1201,7 @@ static gboolean
 __intro_device_added (NMAMobileWizard *self, NMDevice *device, gboolean select_it)
 {
 	GtkTreeIter iter;
-	const char *desc = utils_get_device_description (device);
+	const char *desc = nma_utils_get_device_description (device);
 	NMDeviceModemCapabilities caps;
 
 	if (!NM_IS_DEVICE_MODEM (device))
@@ -1358,7 +1358,7 @@ intro_combo_changed (NMAMobileWizard *self)
 	gtk_tree_model_get (GTK_TREE_MODEL (self->dev_store), &iter,
 	                    INTRO_COL_DEVICE, &selected, -1);
 	if (selected) {
-		self->dev_desc = g_strdup (utils_get_device_description (selected));
+		self->dev_desc = g_strdup (nma_utils_get_device_description (selected));
 		caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (selected));
 		if (caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS)
 			self->method_type = NMN_MOBILE_ACCESS_METHOD_TYPE_GSM;
diff --git a/src/libnm-gtk/nm-ui-utils.c b/src/libnm-gtk/nm-ui-utils.c
new file mode 100644
index 0000000..ad51eac
--- /dev/null
+++ b/src/libnm-gtk/nm-ui-utils.c
@@ -0,0 +1,499 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Applet -- allow user control over networking
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2007 - 2012 Red Hat, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include <glib/gi18n.h>
+#include <gudev/gudev.h>
+
+#include <nm-device.h>
+
+#include "nm-ui-utils.h"
+
+static char *ignored_words[] = {
+	"Semiconductor",
+	"Components",
+	"Corporation",
+	"Communications",
+	"Company",
+	"Corp.",
+	"Corp",
+	"Co.",
+	"Inc.",
+	"Inc",
+	"Incorporated",
+	"Ltd.",
+	"Limited.",
+	"Intel?",
+	"chipset",
+	"adapter",
+	"[hex]",
+	"NDIS",
+	"Module",
+	NULL
+};
+
+static char *ignored_phrases[] = {
+	"Multiprotocol MAC/baseband processor",
+	"Wireless LAN Controller",
+	"Wireless LAN Adapter",
+	"Wireless Adapter",
+	"Network Connection",
+	"Wireless Cardbus Adapter",
+	"Wireless CardBus Adapter",
+	"54 Mbps Wireless PC Card",
+	"Wireless PC Card",
+	"Wireless PC",
+	"PC Card with XJACK(r) Antenna",
+	"Wireless cardbus",
+	"Wireless LAN PC Card",
+	"Technology Group Ltd.",
+	"Communication S.p.A.",
+	"Business Mobile Networks BV",
+	"Mobile Broadband Minicard Composite Device",
+	"Mobile Communications AB",
+	"(PC-Suite Mode)",
+	NULL
+};
+
+static char *
+fixup_desc_string (const char *desc)
+{
+	char *p, *temp;
+	char **words, **item;
+	GString *str;
+
+	p = temp = g_strdup (desc);
+	while (*p) {
+		if (*p == '_' || *p == ',')
+			*p = ' ';
+		p++;
+	}
+
+	/* Attempt to shorten ID by ignoring certain phrases */
+	for (item = ignored_phrases; *item; item++) {
+		guint32 ignored_len = strlen (*item);
+
+		p = strstr (temp, *item);
+		if (p)
+			memmove (p, p + ignored_len, strlen (p + ignored_len) + 1); /* +1 for the \0 */
+	}
+
+	/* Attmept to shorten ID by ignoring certain individual words */
+	words = g_strsplit (temp, " ", 0);
+	str = g_string_new_len (NULL, strlen (temp));
+	g_free (temp);
+
+	for (item = words; *item; item++) {
+		int i = 0;
+		gboolean ignore = FALSE;
+
+		if (g_ascii_isspace (**item) || (**item == '\0'))
+			continue;
+
+		while (ignored_words[i] && !ignore) {
+			if (!strcmp (*item, ignored_words[i]))
+				ignore = TRUE;
+			i++;
+		}
+
+		if (!ignore) {
+			if (str->len)
+				g_string_append_c (str, ' ');
+			g_string_append (str, *item);
+		}
+	}
+	g_strfreev (words);
+
+	temp = str->str;
+	g_string_free (str, FALSE);
+
+	return temp;
+}
+
+#define VENDOR_TAG "nma_utils_get_device_vendor"
+#define PRODUCT_TAG "nma_utils_get_device_product"
+#define DESCRIPTION_TAG "nma_utils_get_device_description"
+
+static void
+get_description (NMDevice *device)
+{
+	char *description = NULL;
+	const char *dev_product;
+	const char *dev_vendor;
+	char *product = NULL;
+	char *vendor = NULL;
+	GString *str;
+
+	dev_product = nm_device_get_product (device);
+	dev_vendor = nm_device_get_vendor (device);
+	if (!dev_product || !dev_vendor) {
+		g_object_set_data (G_OBJECT (device),
+		                   DESCRIPTION_TAG,
+		                   (char *) nm_device_get_ip_iface (device));
+		return;
+	}
+
+	product = fixup_desc_string (dev_product);
+	vendor = fixup_desc_string (dev_vendor);
+
+	str = g_string_new_len (NULL, strlen (vendor) + strlen (product) + 1);
+
+	/* Another quick hack; if all of the fixed up vendor string
+	 * is found in product, ignore the vendor.
+	 */
+	if (!strcasestr (product, vendor)) {
+		g_string_append (str, vendor);
+		g_string_append_c (str, ' ');
+	}
+
+	g_string_append (str, product);
+
+	description = g_string_free (str, FALSE);
+
+	g_object_set_data_full (G_OBJECT (device),
+	                        VENDOR_TAG, vendor,
+	                        (GDestroyNotify) g_free);
+	g_object_set_data_full (G_OBJECT (device),
+	                        PRODUCT_TAG, product,
+	                        (GDestroyNotify) g_free);
+	g_object_set_data_full (G_OBJECT (device),
+	                        DESCRIPTION_TAG, description,
+	                        (GDestroyNotify) g_free);
+}
+
+/**
+ * nma_utils_get_device_vendor:
+ * @device: an #NMDevice
+ *
+ * Gets a cleaned-up version of #NMDevice:vendor for @device. This
+ * removes strings like "Inc." that would just take up unnecessary
+ * space in the UI.
+ *
+ * Returns: a cleaned-up vendor string, or %NULL if the vendor is
+ *   not known
+ */
+const char *
+nma_utils_get_device_vendor (NMDevice *device)
+{
+	const char *vendor;
+
+	g_return_val_if_fail (device != NULL, NULL);
+
+	vendor = g_object_get_data (G_OBJECT (device), VENDOR_TAG);
+	if (!vendor) {
+		get_description (device);
+		vendor = g_object_get_data (G_OBJECT (device), VENDOR_TAG);
+	}
+
+	return vendor;
+}
+
+/**
+ * nma_utils_get_device_product:
+ * @device: an #NMDevice
+ *
+ * Gets a cleaned-up version of #NMDevice:product for @device. This
+ * removes strings like "Wireless LAN Adapter" that would just take up
+ * unnecessary space in the UI.
+ *
+ * Returns: a cleaned-up product string, or %NULL if the product name
+ *   is not known
+ */
+const char *
+nma_utils_get_device_product (NMDevice *device)
+{
+	const char *product;
+
+	g_return_val_if_fail (device != NULL, NULL);
+
+	product = g_object_get_data (G_OBJECT (device), PRODUCT_TAG);
+	if (!product) {
+		get_description (device);
+		product = g_object_get_data (G_OBJECT (device), PRODUCT_TAG);
+	}
+
+	return product;
+}
+
+/**
+ * nma_utils_get_device_description:
+ * @device: an #NMDevice
+ *
+ * Gets a description of @device, incorporating the results of
+ * nma_utils_get_device_vendor() and
+ * nma_utils_get_device_product().
+ *
+ * Returns: a description of @device. If either the vendor or the
+ *   product name is unknown, this returns the interface name.
+ */
+const char *
+nma_utils_get_device_description (NMDevice *device)
+{
+	const char *description;
+
+	g_return_val_if_fail (device != NULL, NULL);
+
+	description = g_object_get_data (G_OBJECT (device), DESCRIPTION_TAG);
+	if (!description) {
+		get_description (device);
+		description = g_object_get_data (G_OBJECT (device), DESCRIPTION_TAG);
+	}
+
+	return description;
+}
+
+static gboolean
+find_duplicates (char     **names,
+                 gboolean  *duplicates,
+                 int        num_devices)
+{
+	int i, j;
+	gboolean found_any = FALSE;
+
+	memset (duplicates, 0, num_devices * sizeof (gboolean));
+	for (i = 0; i < num_devices; i++) {
+		if (duplicates[i])
+			continue;
+		for (j = i + 1; j < num_devices; j++) {
+			if (duplicates[j])
+				continue;
+			if (!strcmp (names[i], names[j]))
+				duplicates[i] = duplicates[j] = found_any = TRUE;
+		}
+	}
+
+	return found_any;
+}
+
+/**
+ * nma_utils_get_device_generic_type_name:
+ * @device: an #NMDevice
+ *
+ * Gets a "generic" name for the type of @device.
+ *
+ * Returns: @device's generic type name
+ */
+const char *
+nma_utils_get_device_generic_type_name (NMDevice *device)
+{
+	switch (nm_device_get_device_type (device)) {
+	case NM_DEVICE_TYPE_ETHERNET:
+	case NM_DEVICE_TYPE_INFINIBAND:
+		return _("Wired");
+	default:
+		return nma_utils_get_device_type_name (device);
+	}
+}
+
+/**
+ * nma_utils_get_device_type_name:
+ * @device: an #NMDevice
+ *
+ * Gets a specific name for the type of @device.
+ *
+ * Returns: @device's generic type name
+ */
+const char *
+nma_utils_get_device_type_name (NMDevice *device)
+{
+	switch (nm_device_get_device_type (device)) {
+	case NM_DEVICE_TYPE_ETHERNET:
+		return _("Ethernet");
+	case NM_DEVICE_TYPE_WIFI:
+		return _("Wi-Fi");
+	case NM_DEVICE_TYPE_BT:
+		return _("Bluetooth");
+	case NM_DEVICE_TYPE_OLPC_MESH:
+		return _("OLPC Mesh");
+	case NM_DEVICE_TYPE_WIMAX:
+		return _("WiMAX");
+	case NM_DEVICE_TYPE_MODEM:
+		return _("Mobile Broadband");
+	case NM_DEVICE_TYPE_INFINIBAND:
+		return _("InfiniBand");
+	case NM_DEVICE_TYPE_BOND:
+		return _("Bond");
+	case NM_DEVICE_TYPE_VLAN:
+		return _("VLAN");
+	case NM_DEVICE_TYPE_ADSL:
+		return _("ADSL");
+	default:
+		return _("Unknown");
+	}
+}
+
+#define BUS_TAG "nm-ui-utils.c:get_bus_name"
+
+static const char *
+get_bus_name (GUdevClient *uclient, NMDevice *device)
+{
+	GUdevDevice *udevice;
+	const char *ifname, *bus;
+	char *display_bus;
+
+	bus = g_object_get_data (G_OBJECT (device), BUS_TAG);
+	if (bus) {
+		if (*bus)
+			return bus;
+		else
+			return NULL;
+	}
+
+	ifname = nm_device_get_iface (device);
+	if (!ifname)
+		return NULL;
+
+	udevice = g_udev_client_query_by_subsystem_and_name (uclient, "net", ifname);
+	if (!udevice)
+		udevice = g_udev_client_query_by_subsystem_and_name (uclient, "tty", ifname);
+	if (!udevice)
+		return NULL;
+
+	bus = g_udev_device_get_property (udevice, "ID_BUS");
+	if (!g_strcmp0 (bus, "pci"))
+		display_bus = g_strdup (_("PCI"));
+	else if (!g_strcmp0 (bus, "usb"))
+		display_bus = g_strdup (_("USB"));
+	else {
+		/* Use "" instead of NULL so we can tell later that we've
+		 * already tried.
+		 */
+		display_bus = g_strdup ("");
+	}
+
+	g_object_set_data_full (G_OBJECT (device),
+	                        BUS_TAG, display_bus,
+	                        (GDestroyNotify) g_free);
+	if (*display_bus)
+		return display_bus;
+	else
+		return NULL;
+}
+
+/**
+ * nma_utils_disambiguate_device_names:
+ * @devices: (array length=num_devices): a set of #NMDevice
+ * @num_devices: length of @devices
+ *
+ * Generates a list of short-ish unique presentation names for the
+ * devices in @devices.
+ *
+ * Returns: (array zero-terminated=1): the device names
+ */
+char **
+nma_utils_disambiguate_device_names (NMDevice **devices,
+                                     int        num_devices)
+{
+	static const char *subsys[3] = { "net", "tty", NULL };
+	GUdevClient *uclient;
+	char **names;
+	gboolean *duplicates;
+	int i;
+
+	names = g_new (char *, num_devices + 1);
+	duplicates = g_new (gboolean, num_devices);
+
+	/* Generic device name */
+	for (i = 0; i < num_devices; i++)
+		names[i] = g_strdup (nma_utils_get_device_generic_type_name (devices[i]));
+	if (!find_duplicates (names, duplicates, num_devices))
+		goto done;
+
+	/* Try specific names (eg, "Ethernet" and "InfiniBand" rather
+	 * than "Wired")
+	 */
+	for (i = 0; i < num_devices; i++) {
+		if (duplicates[i]) {
+			g_free (names[i]);
+			names[i] = g_strdup (nma_utils_get_device_type_name (devices[i]));
+		}
+	}
+	if (!find_duplicates (names, duplicates, num_devices))
+		goto done;
+
+	/* Try prefixing bus name (eg, "PCI Ethernet" vs "USB Ethernet") */
+	uclient = g_udev_client_new (subsys);
+	for (i = 0; i < num_devices; i++) {
+		if (duplicates[i]) {
+			const char *bus = get_bus_name (uclient, devices[i]);
+
+			if (!bus)
+				continue;
+
+			g_free (names[i]);
+			/* Translators: the first %s is a bus name (eg, "USB") or
+			 * product name, the second is a device type (eg,
+			 * "Ethernet"). You can change this to something like
+			 * "%$2s (%$1s)" if there's no grammatical way to combine
+			 * the strings otherwise.
+			 */
+			names[i] = g_strdup_printf (C_("long device name", "%s %s"),
+			                            bus,
+			                            nma_utils_get_device_type_name (devices[i]));
+		}
+	}
+	g_object_unref (uclient);
+	if (!find_duplicates (names, duplicates, num_devices))
+		goto done;
+
+	/* Try prefixing vendor name */
+	for (i = 0; i < num_devices; i++) {
+		if (duplicates[i]) {
+			const char *vendor = nma_utils_get_device_vendor (devices[i]);
+
+			if (!vendor)
+				continue;
+
+			g_free (names[i]);
+			names[i] = g_strdup_printf (C_("long device name", "%s %s"),
+			                            vendor,
+			                            nma_utils_get_device_type_name (devices[i]));
+		}
+	}
+	if (!find_duplicates (names, duplicates, num_devices))
+		goto done;
+
+	/* We have multiple identical network cards, so we have to differentiate
+	 * them by interface name.
+	 */
+	for (i = 0; i < num_devices; i++) {
+		if (duplicates[i]) {
+			const char *interface = nm_device_get_iface (devices[i]);
+
+			if (!interface)
+				continue;
+
+			g_free (names[i]);
+			names[i] = g_strdup_printf ("%s (%s)",
+			                            nma_utils_get_device_type_name (devices[i]),
+			                            interface);
+		}
+	}
+
+ done:
+	g_free (duplicates);
+	names[num_devices] = NULL;
+	return names;
+}
diff --git a/src/libnm-gtk/nm-ui-utils.h b/src/libnm-gtk/nm-ui-utils.h
new file mode 100644
index 0000000..3c09e17
--- /dev/null
+++ b/src/libnm-gtk/nm-ui-utils.h
@@ -0,0 +1,40 @@
+/* NetworkManager Wireless Applet -- Display wireless access points and allow user control
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2007 - 2012 Red Hat, Inc.
+ */
+
+
+/* WARNING: this file is private API between nm-applet and various GNOME
+ * bits; it may change without notice and is not guaranteed to be stable.
+ */
+
+#ifndef NMA_UI_UTILS_H
+#define NMA_UI_UTILS_H
+
+#include <nm-device.h>
+
+const char *nma_utils_get_device_vendor (NMDevice *device);
+const char *nma_utils_get_device_product (NMDevice *device);
+const char *nma_utils_get_device_description (NMDevice *device);
+const char *nma_utils_get_device_generic_type_name (NMDevice *device);
+const char *nma_utils_get_device_type_name (NMDevice *device);
+
+char **nma_utils_disambiguate_device_names (NMDevice **devices,
+                                            int        num_devices);
+
+#endif	/* NMA_UI_UTILS_H */
+
diff --git a/src/libnm-gtk/nm-wifi-dialog.c b/src/libnm-gtk/nm-wifi-dialog.c
index d6e0f26..8b3cd26 100644
--- a/src/libnm-gtk/nm-wifi-dialog.c
+++ b/src/libnm-gtk/nm-wifi-dialog.c
@@ -37,7 +37,7 @@
 
 #include "nm-wifi-dialog.h"
 #include "wireless-security.h"
-#include "utils.h"
+#include "nm-ui-utils.h"
 
 G_DEFINE_TYPE (NMAWifiDialog, nma_wifi_dialog, GTK_TYPE_DIALOG)
 
@@ -576,13 +576,9 @@ static void
 add_device_to_model (GtkListStore *model, NMDevice *device)
 {
 	GtkTreeIter iter;
-	char *desc;
-
-	desc = (char *) utils_get_device_description (device);
-	if (!desc)
-		desc = (char *) nm_device_get_iface (device);
-	g_assert (desc);
+	const char *desc;
 
+	desc = nma_utils_get_device_description (device);
 	gtk_list_store_append (model, &iter);
 	gtk_list_store_set (model, &iter, D_NAME_COLUMN, desc, D_DEV_COLUMN, device, -1);
 }
diff --git a/src/utils/utils.c b/src/utils/utils.c
index 2563929..00f8596 100644
--- a/src/utils/utils.c
+++ b/src/utils/utils.c
@@ -32,157 +32,6 @@
 
 #include "utils.h"
 
-static char *ignored_words[] = {
-	"Semiconductor",
-	"Components",
-	"Corporation",
-	"Communications",
-	"Company",
-	"Corp.",
-	"Corp",
-	"Co.",
-	"Inc.",
-	"Inc",
-	"Incorporated",
-	"Ltd.",
-	"Limited.",
-	"Intel?",
-	"chipset",
-	"adapter",
-	"[hex]",
-	"NDIS",
-	"Module",
-	NULL
-};
-
-static char *ignored_phrases[] = {
-	"Multiprotocol MAC/baseband processor",
-	"Wireless LAN Controller",
-	"Wireless LAN Adapter",
-	"Wireless Adapter",
-	"Network Connection",
-	"Wireless Cardbus Adapter",
-	"Wireless CardBus Adapter",
-	"54 Mbps Wireless PC Card",
-	"Wireless PC Card",
-	"Wireless PC",
-	"PC Card with XJACK(r) Antenna",
-	"Wireless cardbus",
-	"Wireless LAN PC Card",
-	"Technology Group Ltd.",
-	"Communication S.p.A.",
-	"Business Mobile Networks BV",
-	"Mobile Broadband Minicard Composite Device",
-	"Mobile Communications AB",
-	"(PC-Suite Mode)",
-	NULL
-};
-
-static char *
-fixup_desc_string (const char *desc)
-{
-	char *p, *temp;
-	char **words, **item;
-	GString *str;
-
-	p = temp = g_strdup (desc);
-	while (*p) {
-		if (*p == '_' || *p == ',')
-			*p = ' ';
-		p++;
-	}
-
-	/* Attempt to shorten ID by ignoring certain phrases */
-	for (item = ignored_phrases; *item; item++) {
-		guint32 ignored_len = strlen (*item);
-
-		p = strstr (temp, *item);
-		if (p)
-			memmove (p, p + ignored_len, strlen (p + ignored_len) + 1); /* +1 for the \0 */
-	}
-
-	/* Attmept to shorten ID by ignoring certain individual words */
-	words = g_strsplit (temp, " ", 0);
-	str = g_string_new_len (NULL, strlen (temp));
-	g_free (temp);
-
-	for (item = words; *item; item++) {
-		int i = 0;
-		gboolean ignore = FALSE;
-
-		if (g_ascii_isspace (**item) || (**item == '\0'))
-			continue;
-
-		while (ignored_words[i] && !ignore) {
-			if (!strcmp (*item, ignored_words[i]))
-				ignore = TRUE;
-			i++;
-		}
-
-		if (!ignore) {
-			if (str->len)
-				g_string_append_c (str, ' ');
-			g_string_append (str, *item);
-		}
-	}
-	g_strfreev (words);
-
-	temp = str->str;
-	g_string_free (str, FALSE);
-
-	return temp;
-}
-
-#define DESC_TAG "description"
-
-const char *
-utils_get_device_description (NMDevice *device)
-{
-	char *description = NULL;
-	const char *dev_product;
-	const char *dev_vendor;
-	char *product = NULL;
-	char *vendor = NULL;
-	GString *str;
-
-	g_return_val_if_fail (device != NULL, NULL);
-
-	description = g_object_get_data (G_OBJECT (device), DESC_TAG);
-	if (description)
-		return description;
-
-	dev_product = nm_device_get_product (device);
-	dev_vendor = nm_device_get_vendor (device);
-	if (!dev_product || !dev_vendor)
-		return NULL;
-
-	product = fixup_desc_string (dev_product);
-	vendor = fixup_desc_string (dev_vendor);
-
-	str = g_string_new_len (NULL, strlen (vendor) + strlen (product) + 1);
-
-	/* Another quick hack; if all of the fixed up vendor string
-	 * is found in product, ignore the vendor.
-	 */
-	if (!strcasestr (product, vendor)) {
-		g_string_append (str, vendor);
-		g_string_append_c (str, ' ');
-	}
-
-	g_string_append (str, product);
-	g_free (product);
-	g_free (vendor);
-
-	description = str->str;
-	g_string_free (str, FALSE);
-
-	g_object_set_data_full (G_OBJECT (device),
-	                        "description", description,
-	                        (GDestroyNotify) g_free);
-
-	return description;
-}
-
 /*
  * utils_ether_addr_valid
  *
diff --git a/src/utils/utils.h b/src/utils/utils.h
index 96f7b34..0da159a 100644
--- a/src/utils/utils.h
+++ b/src/utils/utils.h
@@ -30,8 +30,6 @@
 #include <net/ethernet.h>
 #include <nm-access-point.h>
 
-const char *utils_get_device_description (NMDevice *device);
-
 guint32 utils_freq_to_channel (guint32 freq);
 guint32 utils_channel_to_freq (guint32 channel, char *band);
 guint32 utils_find_next_channel (guint32 channel, int direction, char *band);



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