Wireshark-dev: Re: [Wireshark-dev] The empty "Tools" menu toplevel item must be removed before

From: Ulf Lamping <ulf.lamping@xxxxxx>
Date: Tue, 17 Oct 2006 23:03:51 +0200
LEGO wrote:
Got it...
gtk_item_factory_get_item() is exactly what I needed!
Right, that's the one to go (sorry, late response, wasn't online).

I've implemented a new function set_menu_visibility() that's working just like the set_menu_sensibility() with the difference that it will hide/show the items :-)

Patch attached, you may find it helpful.

Regards, ULFL
Index: menu.c
===================================================================
--- menu.c	(revision 19566)
+++ menu.c	(working copy)
@@ -107,6 +107,7 @@
 
 static void menus_init(void);
 static void set_menu_sensitivity (GtkItemFactory *, const gchar *, gint);
+static void set_menu_visibility(GtkItemFactory *ifactory, const gchar *path, gboolean visible);
 static void main_toolbar_show_cb(GtkWidget *w _U_, gpointer d _U_);
 static void filter_toolbar_show_cb(GtkWidget *w _U_, gpointer d _U_);
 #ifdef HAVE_AIRPCAP
@@ -598,6 +599,7 @@
                        init_conversation_notebook_cb, 0, WIRESHARK_STOCK_CONVERSATIONS),
     ITEM_FACTORY_STOCK_ENTRY("/Statistics/Endpoints", NULL,
                        init_hostlist_notebook_cb, 0, WIRESHARK_STOCK_ENDPOINTS),
+    ITEM_FACTORY_ENTRY("/_Tools", NULL, NULL, 0, "<Branch>", NULL),
     ITEM_FACTORY_ENTRY("/_Help", NULL, NULL, 0, "<Branch>", NULL),
     ITEM_FACTORY_STOCK_ENTRY("/Help/_Contents", "F1", topic_menu_cb, HELP_CONTENT, GTK_STOCK_HELP),
     ITEM_FACTORY_ENTRY("/Help/_Supported Protocols", NULL, supported_cb, 0, NULL, NULL),
@@ -846,6 +848,9 @@
 
     /* init with an empty recent files list */
     clear_menu_recent_capture_file_cmd_cb(NULL, NULL);
+
+    /* until we have Tools available, hide that top level item for now (will e.g. used by lua scripts) */
+    set_menu_visibility(main_menu_factory, "/Tools", FALSE);
   }
 }
 
@@ -1216,7 +1221,70 @@
   g_free(dup);
 }
 
+/*
+ * Enable/disable menu visibility.
+ */
 static void
+set_menu_visibility(GtkItemFactory *ifactory, const gchar *path, gboolean visible)
+{
+  GSList *menu_list;
+  GtkWidget *menu_item;
+  gchar *dup;
+  gchar *dest;
+
+
+  /* the underscore character regularly confuses things, as it will prevent finding
+   * the menu_item, so it has to be removed first */
+  dup = g_strdup(path);
+  dest = dup;
+  while(*path) {
+      if (*path != '_') {
+        *dest = *path;
+        dest++;
+      }
+      path++;
+  }
+  *dest = '\0';
+
+  if (ifactory == NULL) {
+    /*
+     * Do it for all pop-up menus.
+     */
+    for (menu_list = popup_menu_list; menu_list != NULL;
+         menu_list = g_slist_next(menu_list))
+      set_menu_visibility(menu_list->data, dup, visible);
+  } else {
+    /*
+     * Do it for that particular menu.
+     */
+    if ((menu_item = gtk_item_factory_get_widget(ifactory, dup)) != NULL) {
+      if (GTK_IS_MENU(menu_item)) {
+        /*
+         * "dup" refers to a submenu; "gtk_item_factory_get_widget()"
+         * gets the menu, not the item that, when selected, pops up
+         * the submenu.
+         *
+         * We have to change the latter item's sensitivity, so that
+         * it shows up normally if sensitive and grayed-out if
+         * insensitive.
+         */
+        menu_item = gtk_menu_get_attach_widget(GTK_MENU(menu_item));
+      }
+      if(visible) {
+        gtk_widget_show(menu_item);
+      } else {
+        gtk_widget_hide(menu_item);
+      }
+    } else{
+      /* be sure this menu item *is* existing */
+      g_assert_not_reached();
+    }
+  }
+
+  g_free(dup);
+}
+
+static void
 set_menu_object_data_meat(GtkItemFactory *ifactory, const gchar *path, const gchar *key, gpointer data)
 {
 	GtkWidget *menu = NULL;