Huge thanks to our Platinum Members Endace and LiveAction,
and our Silver Member Veeam, for supporting the Wireshark Foundation and project.

Wireshark-dev: Re: [Wireshark-dev] [Wireshark-commits] rev 36978: /trunk/gtk/ /trunk/gtk/: io_s

From: Anders Broman <a.broman@xxxxxxxxxxxx>
Date: Wed, 04 May 2011 00:05:50 +0200
Joerg Mayer skrev 2011-05-03 23:28:
On Tue, May 03, 2011 at 04:51:13PM +0000, etxrab@xxxxxxxxxxxxx wrote:
http://anonsvn.wireshark.org/viewvc/viewvc.cgi?view=rev&revision=36978
Log:
  Do some prep work on GUIManager code, if you enable it it will break as the menus.c changes are not commited.
IMO there is no justification for checking in code that breaks compilation,
even with experiemental/development features.
If this happens accidentally it's embarrasing enough ;-) but knowingly
breaking things for people who have the experimental stuff turned on isn't
very nice.

Ciao
   Joerg
Hi,
My apologises, my excuse is that I didn't think any one used it and I have 2 development machines and it's easier to use svn than copying files. The menu.c code is only done for the MAIN_MENU_USE_UIMANAGER
branch yet.
Attaching a diff.
I hope to clean up the code tomorrow.
Best regards
Anders
Index: menus.c
===================================================================
--- menus.c	(revision 36980)
+++ menus.c	(working copy)
@@ -127,12 +127,19 @@
 static GtkAccelGroup *grp;
 
 typedef struct _menu_item {
-    char    *name;
-    gint    group;
-    const char *label;
-    const char *stock_id;
+    gint          group;
+    const char   *gui_path;
+    const char   *name;
+    const char   *stock_id;
+    const char   *label;
+    const char   *accelerator;
+    const gchar  *tooltip;
+#ifdef MAIN_MENU_USE_UIMANAGER
+    GCallback    callback;
+#else
+    GtkItemFactoryCallback callback;
+#endif
     gboolean enabled;
-    GtkItemFactoryCallback callback;
     gpointer callback_data;
     gboolean (*selected_packet_enabled)(frame_data *, epan_dissect_t *, gpointer callback_data);
     gboolean (*selected_tree_row_enabled)(field_info *, gpointer callback_data);
@@ -1163,6 +1170,7 @@
 #endif /* HAVE_LIBPCAP */
 "    <menu name= 'AnalyzeMenu' action='/Analyze'>\n"
 "      <menuitem name='DisplayFilters' action='/Analyze/DisplayFilters'/>\n"
+"      <menuitem name='DisplayFilterMacros' action='/Analyze/DisplayFilterMacros'/>\n"
 "      <separator/>\n"
 "      <menuitem name='ApplyasColumn' action='/Analyze/ApplyasColumn'/>\n"
 "      <menu name= 'ApplyAsFilter' action='/Analyze/ApplyasFilter'>\n"
@@ -1181,6 +1189,7 @@
 "        <menuitem name='AndNotSelected' action='/Analyze/PrepareaFilter/AndNotSelected'/>\n"
 "        <menuitem name='OrNotSelected' action='/Analyze/PrepareaFilter/OrNotSelected'/>\n"
 "      </menu>\n"
+"      <separator/>\n"
 "      <menuitem name='EnabledProtocols' action='/Analyze/EnabledProtocols'/>\n"
 "      <menuitem name='DecodeAs' action='/Analyze/DecodeAs'/>\n"
 "      <menuitem name='UserSpecifiedDecodes' action='/Analyze/UserSpecifiedDecodes'/>\n"
@@ -1188,14 +1197,26 @@
 "      <menuitem name='FollowTCPStream' action='/Analyze/FollowTCPStream'/>\n"
 "      <menuitem name='FollowUDPStream' action='/Analyze/FollowUDPStream'/>\n"
 "      <menuitem name='FollowSSLStream' action='/Analyze/FollowSSLStream'/>\n"
+"      <placeholder name='ExpertInfoComposite'/>\n"
+"      <menu name= 'ConversationFilterMenu' action='/Analyze/ConversationFilter'>\n"
+"        <placeholder name='Filters'/>\n"
+"      </menu>\n"
 "    </menu>\n"
 "    <menu name= 'StatisticsMenu' action='/Statistics'>\n"
 "      <menuitem name='Summary' action='/Statistics/Summary'/>\n"
 "      <menuitem name='ProtocolHierarchy' action='/Statistics/ProtocolHierarchy'/>\n"
 "      <menuitem name='Conversations' action='/Statistics/Conversations'/>\n"
 "      <menuitem name='Endpoints' action='/Statistics/Endpoints'/>\n"
+"      <placeholder name='IOGraphs'/>\n"
+"      <separator/>\n"
+"      <placeholder name='FlowGraph'/>\n"
+"      <separator/>\n"
+"      <menu name= 'ConversationListMenu' action='/Analyze/ConversationList'>\n"
+"        <placeholder name='List-item'/>\n"
+"      </menu>\n"
 "    </menu>\n"
 "    <menu name= 'TelephonyMenu' action='/Telephony'>\n"
+"      <placeholder name='VoIPCalls'/>\n"
 "    </menu>\n"
 "    <menu name= 'ToolsMenu' action='/Tools'>\n"
 "      <menuitem name='FirewallACLRules' action='/Tools/FirewallACLRules'/>\n"
@@ -1515,7 +1536,9 @@
    { "/Analyze/FollowUDPStream",							NULL,		"Follow UDP Stream",					NULL, NULL, G_CALLBACK(follow_udp_stream_cb) },
    { "/Analyze/FollowSSLStream",							NULL,		"Follow SSL Stream",					NULL, NULL, G_CALLBACK(follow_ssl_stream_cb) },
 
- 
+   { "/Analyze/ConversationFilter",						NULL,			"Conversation Filter",					NULL, NULL, NULL },
+   { "/Analyze/ConversationList",							NULL,		"_Conversation List",					NULL, NULL, NULL },
+
    { "/Statistics/Summary",			GTK_STOCK_PROPERTIES,			"_Summary",				NULL,							NULL,				G_CALLBACK(summary_open_cb) },
    { "/Statistics/ProtocolHierarchy",				NULL,			"_Protocol Hierarchy",	NULL,							NULL,				G_CALLBACK(proto_hier_stats_cb) },
    { "/Statistics/Conversations",	WIRESHARK_STOCK_CONVERSATIONS,	"Conversations",		NULL,							NULL,				G_CALLBACK(init_conversation_notebook_cb) },
@@ -3318,11 +3341,17 @@
     return menubar;
 }
 
-
-void menu_dissector_filter_cb(  GtkWidget *widget _U_,
+#ifdef MAIN_MENU_USE_UIMANAGER
+static void
+menu_dissector_filter_cb(  GtkAction *action _U_,  gpointer callback_data)
+{
+#else
+static void
+menu_dissector_filter_cb(  GtkWidget *widget _U_,
                                 gpointer callback_data,
                                 guint callback_action _U_)
 {
+#endif
     dissector_filter_t      *filter_entry = callback_data;
     GtkWidget               *filter_te;
     const char              *buf;
@@ -3359,11 +3388,27 @@
     while(list_entry != NULL) {
         filter_entry = list_entry->data;
 
+#ifdef MAIN_MENU_USE_UIMANAGER
+	register_stat_menu_item_stock(
+		REGISTER_ANALYZE_GROUP_CONVERSATION_FILTER,	  /* Group */
+		"/Menubar/AnalyzeMenu/ConversationFilterMenu/Filters", /* GUI path */
+		filter_entry->name,                           /* Name */
+		NULL,                                         /* stock_id */
+		filter_entry->name,                           /* label */
+		NULL,                                         /* accelerator */
+		NULL,                                         /* tooltip */
+		G_CALLBACK(menu_dissector_filter_cb),         /* callback */
+		FALSE,                                        /* enabled */
+		menu_dissector_filter_spe_cb,                 /* selected_packet_enabled */
+		NULL,                                         /* selected_tree_row_enabled */
+		filter_entry);                                /* callback_data */
+#else
         register_stat_menu_item(filter_entry->name, REGISTER_ANALYZE_GROUP_CONVERSATION_FILTER,
             menu_dissector_filter_cb,
             menu_dissector_filter_spe_cb,
             NULL /* selected_tree_row_enabled */,
             filter_entry);
+#endif
 
         list_entry = g_list_next(list_entry);
     }
@@ -3634,11 +3679,19 @@
 
 /* add a menuitem below the current node */
 static GList * tap_menu_item_add(
-    char *name,
-    gint group,
+    gint        group,
+    const char *gui_path,
+    const char *name,
     const char *label,
     const char *stock_id,
+    const char *accelerator,
+    const char *tooltip,
+#ifdef MAIN_MENU_USE_UIMANAGER
+    GCallback   callback,
+#else
     GtkItemFactoryCallback callback,
+#endif
+    gboolean    enabled,
     gboolean (*selected_packet_enabled)(frame_data *, epan_dissect_t *, gpointer callback_data),
     gboolean (*selected_tree_row_enabled)(field_info *, gpointer callback_data),
     gpointer callback_data,
@@ -3649,15 +3702,19 @@
 
 
     child = g_malloc(sizeof (menu_item_t));
+    child->group            = group;
+    child->gui_path         = gui_path;
     child->name             = name;
-    child->group            = group;
     child->label            = label;
     child->stock_id         = stock_id;
+    child->accelerator      = accelerator;
+    child->stock_id         = stock_id;
+    child->tooltip          = tooltip;
     child->callback         = callback;
+	child->enabled          = enabled;
     child->selected_packet_enabled = selected_packet_enabled;
     child->selected_tree_row_enabled = selected_tree_row_enabled;
     child->callback_data    = callback_data;
-    child->enabled          = FALSE;
     child->children         = NULL;
 
     /* insert the new child node into the parent */
@@ -3693,13 +3750,28 @@
 
 void
 register_stat_menu_item_stock(
+#ifdef MAIN_MENU_USE_UIMANAGER
+    register_stat_group_t group,
+    const char *gui_path,
     const char *name,
+    const char *stock_id,
+	const char *label,
+	const char *accelerator,
+	const char *tooltip,
+    GCallback   callback,
+	gboolean    enabled,
+    gboolean (*selected_packet_enabled)(frame_data *, epan_dissect_t *, gpointer callback_data),
+    gboolean (*selected_tree_row_enabled)(field_info *, gpointer callback_data),
+    gpointer callback_data)
+#else
+    const char *name,
     register_stat_group_t group,
     const char *stock_id,
     GtkItemFactoryCallback callback,
     gboolean (*selected_packet_enabled)(frame_data *, epan_dissect_t *, gpointer callback_data),
     gboolean (*selected_tree_row_enabled)(field_info *, gpointer callback_data),
     gpointer callback_data)
+#endif
 {
     /*static const char toolspath[] = "/Statistics/";*/
     const char *toolspath;
@@ -3784,8 +3856,13 @@
              * No.  Create such an item as a subtree, and
              * add it to the Tools menu tree.
              */
+#ifdef MAIN_MENU_USE_UIMANAGER
             childnode = tap_menu_item_add(
+                group, (const char*)menupath, name, label, NULL, NULL, NULL, NULL ,FALSE, NULL, NULL, NULL, curnode);
+#else
+            childnode = tap_menu_item_add(
                 menupath, group, name, "", NULL, NULL ,NULL, NULL, curnode);
+#endif
         } else {
             /*
              * Yes.  We don't need this "menupath" any longer.
@@ -3812,10 +3889,18 @@
      * Construct an item factory entry for the item, and add it to
      * the main menu.
      */
+#ifdef MAIN_MENU_USE_UIMANAGER
     tap_menu_item_add(
-        menupath, group, name, stock_id, callback,
+        group, gui_path, name, label, stock_id, 
+        accelerator, tooltip, callback, enabled,
         selected_packet_enabled, selected_tree_row_enabled,
         callback_data, curnode);
+#else
+    tap_menu_item_add(
+        group, menupath, name, stock_id, callback,
+        selected_packet_enabled, selected_tree_row_enabled,
+        callback_data, curnode);
+#endif
 }
 
 /*
@@ -3855,7 +3940,10 @@
     gboolean (*selected_tree_row_enabled)(field_info *, gpointer callback_data),
     gpointer callback_data)
 {
+#ifdef MAIN_MENU_USE_UIMANAGER
+#else
     register_stat_menu_item_stock(
+		NULL,                       
         name,
         group,
         NULL,
@@ -3863,21 +3951,65 @@
         selected_packet_enabled,
         selected_tree_row_enabled,
         callback_data);
+#endif
 }
 
 #ifdef MAIN_MENU_USE_UIMANAGER
+static void
+add_menu_item(menu_item_t *node_data){
+    GtkActionGroup *action_group = NULL;
+    GtkAction *action;
+	GList *action_groups, *l;
+	guint merge_id;
+
+	g_warning("path '%s', node_data->name '%s'",node_data->gui_path,node_data->name);
+	if(node_data->stock_id){
+		g_warning("node_data->stock_id %s",node_data->stock_id);
+	}
+
+	action_groups = gtk_ui_manager_get_action_groups (ui_manager_main_menubar);
+    for (l = action_groups; l != NULL; l = l->next)
+    {
+        GtkActionGroup *group = l->data;
+
+        if (strcmp (gtk_action_group_get_name (group), "MenuActionGroup") == 0){
+            /* This unrefs the action group and all of its actions */
+            action_group = group;
+            break;
+       }
+    }
+	if(!action_group){
+		g_warning("Failed to find the action group");
+		return;
+	}
+	merge_id = gtk_ui_manager_new_merge_id (ui_manager_main_menubar);
+
+    action = g_object_new (GTK_TYPE_ACTION,
+               "name", node_data->name,
+               "label", node_data->label,
+			   "stock_id", node_data->stock_id,
+               "sensitive", node_data->enabled,
+               NULL);
+    gtk_action_group_add_action (action_group, action);
+    g_signal_connect (action, "activate",
+               G_CALLBACK (node_data->callback), node_data->callback_data);
+
+    g_object_unref (action);
+
+    gtk_ui_manager_add_ui (ui_manager_main_menubar, merge_id,
+               node_data->gui_path,
+               node_data->name, /* XXX is this ok, the name for the added UI element  */
+               node_data->name, /* the name of the action to be proxied, or NULL to add a separator */
+               GTK_UI_MANAGER_MENUITEM,
+               FALSE);
+
+}
+
 static guint merge_tap_menus_layered(GList *node, gint group) {
-    GtkItemFactoryEntry *entry;
-#if 0
-    gchar *p;
-#endif
-    GtkAction *action;
-    guint merge_id;
-    GtkActionGroup *action_group;
+    /*GtkItemFactoryEntry *entry;*/
     GList       *child;
     guint       added = 0;
     menu_item_t *node_data = node->data;
-    gchar       *action_grp_name;
 
     /*
      * Is this a leaf node or an interior node?
@@ -3892,31 +4024,37 @@
          * has a null name pointer.
          */
         if (node_data->name != NULL && group == node_data->group) {
-            entry = g_malloc0(sizeof (GtkItemFactoryEntry));
-            entry->path = node_data->name;
-            entry->callback = node_data->callback;
+           /* entry = g_malloc0(sizeof (GtkItemFactoryEntry));*/
+            /*entry->path = node_data->name;*/
+           /* entry->callback = node_data->callback;*/
             switch(group) {
             case(REGISTER_STAT_GROUP_UNSORTED):
+				add_menu_item(node_data);
                 break;
             case(REGISTER_STAT_GROUP_GENERIC):
+				add_menu_item(node_data);
                 break;
             case(REGISTER_STAT_GROUP_CONVERSATION_LIST):
-                entry->item_type = "<StockItem>";
-                entry->extra_data = WIRESHARK_STOCK_CONVERSATIONS;
+				add_menu_item(node_data);
+                /*entry->item_type = "<StockItem>";*/
+                /*entry->extra_data = WIRESHARK_STOCK_CONVERSATIONS;*/
                 break;
             case(REGISTER_STAT_GROUP_ENDPOINT_LIST):
-                entry->item_type = "<StockItem>";
-                entry->extra_data = WIRESHARK_STOCK_ENDPOINTS;
+                /*entry->item_type = "<StockItem>";*/
+                /*entry->extra_data = WIRESHARK_STOCK_ENDPOINTS;*/
                 break;
             case(REGISTER_STAT_GROUP_RESPONSE_TIME):
-                entry->item_type = "<StockItem>";
-                entry->extra_data = WIRESHARK_STOCK_TIME;
+                /*entry->item_type = "<StockItem>";*/
+                /*entry->extra_data = WIRESHARK_STOCK_TIME;*/
                 break;
             case(REGISTER_STAT_GROUP_TELEPHONY):
+				add_menu_item(node_data);
                 break;
             case(REGISTER_ANALYZE_GROUP_UNSORTED):
+				add_menu_item(node_data);
                 break;
             case(REGISTER_ANALYZE_GROUP_CONVERSATION_FILTER):
+				add_menu_item(node_data);
                 break;
             case(REGISTER_TOOLS_GROUP_UNSORTED):
                 break;
@@ -3924,8 +4062,8 @@
                 g_assert_not_reached();
             }
             if(node_data->stock_id!= NULL) {
-                entry->item_type = "<StockItem>";
-                entry->extra_data = node_data->stock_id;
+               /* entry->item_type = "<StockItem>";*/
+                /*entry->extra_data = node_data->stock_id;*/
             }
 #if 0
             gtk_item_factory_create_item(main_menu_factory, entry, node_data->callback_data, /* callback_type */ 2);
@@ -3945,88 +4083,7 @@
          * has a null name pointer.
          */
         if (node_data->name != NULL && group == node_data->group) {
-            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(node_data->name);
-            dest = dup;
-            while(*node_data->name) {
-                if (*node_data->name != '_') {
-                    *dest = *node_data->name;
-                    dest++;
-                }
-                node_data->name++;
-            }
-            *dest = '\0';
-
-            entry = g_malloc0(sizeof (GtkItemFactoryEntry));
-            entry->path = node_data->name;
-            entry->item_type = "<Branch>";
-            /* use the node_data->name(path) with the slashes replaced by "-" as the action group name */
-            action_grp_name = g_strdup(dup+1);
-            g_strdelimit(action_grp_name, "/", '-');
-
-            g_warning("<Branch> %s",action_grp_name);
-
-
-            action_group = gtk_action_group_new (action_grp_name);
-            switch(group) {
-            case(REGISTER_STAT_GROUP_UNSORTED):
-                merge_id = gtk_ui_manager_new_merge_id (ui_manager_main_menubar);
-                gtk_ui_manager_insert_action_group (ui_manager_main_menubar, action_group, 0);
-                g_object_set_data (G_OBJECT (ui_manager_main_menubar),
-                    "Menubar-StatisticsMenu-merge-id", GUINT_TO_POINTER (merge_id));
-
-                action = gtk_action_new(node_data->name,				/* name */
-                           strrchr(node_data->name,'/'),				/* label */
-                           NULL,										/* tooltip */
-                           node_data->stock_id);						/* stock_id */
-
-                gtk_action_group_add_action (action_group, action);
-                g_object_unref (action);
-
-                gtk_ui_manager_add_ui (ui_manager_main_menubar, merge_id,
-                           "/Menubar/StatisticsMenu",            /* path */
-                           strrchr(node_data->name,'/'),         /* name */
-                           node_data->name,                      /* action */
-                           GTK_UI_MANAGER_MENU,                  /* type */
-                           FALSE);                               /* "top" if TRUE, the UI element is added before its siblings */
-
-
-                g_warning("<Stat unsorted> %s",action_grp_name);
-                g_warning("label %s",node_data->label);
-                break;
-            case(REGISTER_STAT_GROUP_GENERIC):
-                break;
-            case(REGISTER_STAT_GROUP_ENDPOINT_LIST):
-                break;
-            case(REGISTER_STAT_GROUP_RESPONSE_TIME):
-                break;
-            case(REGISTER_STAT_GROUP_TELEPHONY):
-                break;
-            case(REGISTER_ANALYZE_GROUP_UNSORTED):
-                break;
-            case(REGISTER_ANALYZE_GROUP_CONVERSATION_FILTER):
-                break;
-            case(REGISTER_TOOLS_GROUP_UNSORTED):
-                g_warning("<Tools> %s",action_grp_name);
-                g_warning("label %s",node_data->label);
-                break;
-            default:
-                g_assert_not_reached();
-            }
-
-#if 0
-            gtk_item_factory_create_item(main_menu_factory, entry,
-                NULL, 2);
-            set_menu_sensitivity_old(main_menu_factory, node_data->name,
-                FALSE);    /* no children yet */
-            added++;
-            g_free(entry);
-#endif
+			/* We don't create the sub-menus */
         }
 
         for (child = node_data->children; child != NULL; child =