Checking for underline-duplicates in menus



I added the code below to (so far my copy of) Gnumeric and I get the
following warnings in the C locale when calling check_underlines with
the menubar widget:

** (gnumeric:29534): WARNING **: In the `File' menu, the key `C' is used for both `Preferences...' and `Close'.
** (gnumeric:29534): WARNING **: In the `Format' menu, the key `C' is used for both `Cells...' and `Preferences...'.

Other locales have tons of collisions -- apparently this is not something
that translators can easily detect.

The point here is that this code really has no business sitting in
Gnumeric.  It should live somewhere in GTK+.

Morten






static const char *
get_accel_label (GtkMenuItem *item, char *key)
{
	GList *children = gtk_container_get_children (GTK_CONTAINER (item));
	GList *l;
	const char *res = NULL;

	*key = 0;
	for (l = children; l; l = l->next) {
		GtkWidget *w = l->data;

		if (GTK_IS_ACCEL_LABEL (w)) {
			const char *label = gtk_label_get_label (GTK_LABEL (w));
			*key = 0;
			while (*label) {
				if (*label == '_') {
					*key = g_ascii_toupper (label[1]);
					break;
				}
				label++;
			}
			res = gtk_label_get_text (GTK_LABEL (w));
			break;
		}
	}

	g_list_free (children);
	return res;
}

static void
check_underlines (GtkWidget *w, const char *path)
{
	GList *children = gtk_container_get_children (GTK_CONTAINER (w));
	GHashTable *used = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify)g_free);
	GList *l;

	for (l = children; l; l = l->next) {
		GtkMenuItem *item = GTK_MENU_ITEM (l->data);
		GtkWidget *sub = gtk_menu_item_get_submenu (item);
		char key;
		const char *label = get_accel_label (item, &key);

		if (sub) {
			char *newpath = g_strconcat (path, *path ? "->" : "", label, NULL);
			check_underlines (sub, newpath);
			g_free (newpath);
		}

		if (key) {
			const char *prev = g_hash_table_lookup (used, GINT_TO_POINTER ((int)key));
			if (prev)
				g_warning ("In the `%s' menu, the key `%c' is used for both `%s' and `%s'.",
					   path, key, prev, label);
			else
				g_hash_table_insert (used, GINT_TO_POINTER ((int)key), g_strdup (label));
		}
	}

	g_list_free (children);
	g_hash_table_destroy (used);
}



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