aboutsummaryrefslogtreecommitdiffstats
path: root/gtk
diff options
context:
space:
mode:
authorAnders Broman <anders.broman@ericsson.com>2011-10-14 05:08:39 +0000
committerAnders Broman <anders.broman@ericsson.com>2011-10-14 05:08:39 +0000
commit5902e7fa0651b3f048bdddcd88511566b9e5b218 (patch)
tree44a2877eb44d23cd1e2e7eda5d257482850bd074 /gtk
parent59891bb9e4d3097ae6efd05281927577b457ec1f (diff)
From Tony Trinh:
Patch to fix/restore Lua menu functionality Remove unnecessary Lua placeholder in UI definition for the main menu bar https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=6405 svn path=/trunk/; revision=39410
Diffstat (limited to 'gtk')
-rw-r--r--gtk/funnel_stat.c19
-rw-r--r--gtk/main_menubar.c280
2 files changed, 255 insertions, 44 deletions
diff --git a/gtk/funnel_stat.c b/gtk/funnel_stat.c
index 29d8b1a25a..82911b7bb4 100644
--- a/gtk/funnel_stat.c
+++ b/gtk/funnel_stat.c
@@ -607,6 +607,21 @@ static void our_menu_callback(void* unused _U_, gpointer data) {
if (mcb->retap) cf_retap_packets(&cfile);
}
+static const char* stat_group_name(register_stat_group_t group _U_) {
+ static const value_string VALS_GROUP_NAMES[] = {
+ {REGISTER_ANALYZE_GROUP_UNSORTED, "/Menubar/AnalyzeMenu|_Analyze"}, /* unsorted analyze stuff */
+ {REGISTER_ANALYZE_GROUP_CONVERSATION_FILTER, "/Menubar/AnalyzeMenu/ConversationFilterMenu|Conversation Filter"}, /* conversation filters */
+ {REGISTER_STAT_GROUP_UNSORTED, "/Menubar/StatisticsMenu|Statistics"}, /* unsorted statistic function */
+ {REGISTER_STAT_GROUP_GENERIC, "/Menubar/StatisticsMenu|Statistics"}, /* generic statistic function, not specific to a protocol */
+ {REGISTER_STAT_GROUP_CONVERSATION_LIST, "/Menubar/StatisticsMenu|Statistics/ConversationListMenu|_Conversation List"}, /* member of the conversation list */
+ {REGISTER_STAT_GROUP_ENDPOINT_LIST, "/Menubar/StatisticsMenu|Statistics/EndpointListMenu|_Endpoint List"}, /* member of the endpoint list */
+ {REGISTER_STAT_GROUP_RESPONSE_TIME, "/Menubar/StatisticsMenu|Statistics/ServiceResponseTimeMenu|Service _Response Time"}, /* member of the service response time list */
+ {REGISTER_STAT_GROUP_TELEPHONY, "/Menubar/TelephonyMenu|Telephon_y"}, /* telephony specific */
+ {REGISTER_TOOLS_GROUP_UNSORTED, "/Menubar/ToolsMenu|_Tools"} /* unsorted tools */
+ };
+ return val_to_str_const(group, VALS_GROUP_NAMES, "/Menubar/ToolsMenu|_Tools");
+}
+
static void register_menu_cb(const char *name,
register_stat_group_t group _U_,
void (*callback)(gpointer),
@@ -628,8 +643,8 @@ static void register_menu_cb(const char *name,
}
register_lua_menu_bar_menu_items(
- "/Menubar/ToolsMenu/LUA/LUA-menu-items", /* GUI path to the place holder in the menu */
- name, /* Action mame */
+ stat_group_name(group), /* GUI path to the place holder in the menu */
+ name, /* Action name */
NULL, /* Stock id */
label, /* label */
NULL, /* Accelerator */
diff --git a/gtk/main_menubar.c b/gtk/main_menubar.c
index c7c151d072..3efcaec726 100644
--- a/gtk/main_menubar.c
+++ b/gtk/main_menubar.c
@@ -1326,9 +1326,6 @@ static const char *ui_desc_menubar =
" </menu>\n"
" <menu name= 'ToolsMenu' action='/Tools'>\n"
" <menuitem name='FirewallACLRules' action='/Tools/FirewallACLRules'/>\n"
-" <menu name='LUA' action='/Tools/LUA'>\n"
-" <placeholder name='LUA-menu-items'/>\n"
-" </menu>\n"
" </menu>\n"
" <menu name= 'InternalsMenu' action='/Internals'>\n"
" <menuitem name='Dissectortables' action='/Internals/Dissectortables'/>\n"
@@ -1789,7 +1786,6 @@ static const GtkActionEntry main_menu_bar_entries[] = {
{ "/Telephony/WSP", NULL, "_WAP-WSP...", NULL, NULL, G_CALLBACK(wsp_stat_cb) },
{ "/Tools/FirewallACLRules", NULL, "Firewall ACL Rules", NULL, NULL, G_CALLBACK(firewall_rule_cb) },
- { "/Tools/LUA", NULL, "LUA", NULL, NULL, NULL },
{ "/Internals/Dissectortables", NULL, "_Dissector tables", NULL, NULL, G_CALLBACK(dissector_tables_dlg_cb) },
{ "/Internals/SupportedProtocols", NULL, "_Supported Protocols (slow!)", NULL, NULL, G_CALLBACK(supported_cb) },
@@ -3470,7 +3466,7 @@ menus_init(void) {
popup_menu_list = g_slist_append((GSList *)popup_menu_list, ui_manager_statusbar_profiles_menu);
menu_dissector_filter(&cfile);
- /* Only LUA uses this currently. NOTE that "placeholders" must exist in the GUI description */
+ /* Only Lua uses this currently. */
merge_lua_menu_items(merge_lua_menu_items_list);
/* Add external menus and items */
@@ -3573,52 +3569,252 @@ void register_lua_menu_bar_menu_items(
}
-static void
-merge_lua_menu_items(GList *merge_lua_menu_items_list _U_)
-{
-#ifdef HAVE_LUA
- guint merge_id;
- GtkActionGroup *action_group;
- GtkAction *action;
- GtkWidget *lua_submenu;
- gchar *action_name;
- guint i = 0;
- menu_item_t *menu_item_data;
+#define XMENU_MAX_DEPTH (1 + 32) /* max number of menus in an xpath (+1 for Menubar) */
+#define XMENU_HEADER "<ui><menubar name='Menubar'>\n"
+#define XMENU_FOOTER "</menubar></ui>\n"
- merge_id = gtk_ui_manager_new_merge_id (ui_manager_main_menubar);
+/**
+ * Creates an XML string, containing a UI definition that can be merged
+ * with Wireshark's menu bar using gtk_ui_manager_add_ui_from_string().
+ * Free the returned string with g_free() when no longer needed.
+ *
+ * The last item in the path is treated as the menu item; all preceding path
+ * elements are the names of parent menus. Path elements are stripped of
+ * leading/trailing spaces.
+ *
+ * Examples:
+ * make_menu_xml("/Foo/Bar/I_tem");
+ * -->
+ * "<ui><menubar name='Menubar'>
+ * <menu action='Foo'>
+ * <menu action='Bar'>
+ * <menuitem action='I_tem'/> <!-- puts shortcut on 't' -->
+ * </menu>
+ * </menu>
+ * <menubar></ui>"
+ *
+ * make_menu_xml("/Foo/Bar/-/Baz/Item");
+ * -->
+ * "<ui><menubar name='Menubar'>
+ * <menu action='Foo'>
+ * <menu action='Bar'>
+ * <separator/>
+ * <menu action='Baz'>
+ * <menuitem action='Item'/>
+ * </menu>
+ * </menu>
+ * </menu>
+ * <menubar></ui>"
+ *
+ * http://developer.gnome.org/gtk/2.24/GtkUIManager.html#XML-UI
+ * http://developer.gnome.org/gtk/2.24/GtkUIManager.html#gtk-ui-manager-add-ui-from-string
+ */
+const gchar*
+make_menu_xml(const char *path) {
+ GString *xml;
+ char **p;
+ char **tokens;
+ const char *tok = path;
+ char *lbl;
+ gchar *markup;
+ guint num_menus;
+ size_t len;
+
+ if (path == NULL) return NULL;
+
+ xml = g_string_new(XMENU_HEADER);
+
+ /* no need to specify menu bar...skip it */
+ len = strlen("/Menubar");
+ if (g_ascii_strncasecmp(path, "/Menubar", len) == 0) {
+ path += len;
+ }
+
+ /* open nested menu tag for each path token */
+ num_menus = 0;
+ tokens = g_strsplit(path, "/", XMENU_MAX_DEPTH);
+ for (p = tokens; (p != NULL) && (*p != NULL); p++) {
- action_group = gtk_action_group_new ("LUA-action-group");
+ tok = g_strstrip(*p);
+ if (tok[0] == '\0') continue;
- lua_submenu = gtk_ui_manager_get_widget(ui_manager_main_menubar, "/Menubar/ToolsMenu/LUA");
- if(!lua_submenu){
- g_warning("lua_submenu: No submenu for LUA found, path= /Menubar/ToolsMenu/LUA");
+ /* reserve last token for menu-item processing */
+ if (*(p+1) == NULL) break;
+
+ if (g_strcmp0(tok, "-") == 0) {
+ xml = g_string_append(xml, "<separator/>\n");
+ } else {
+ /* strip label from token...it's used later in menu actions */
+ lbl = strchr(tok, '|');
+ if (lbl != NULL) *lbl++ = '\0';
+
+ markup = g_markup_printf_escaped("<menu action='%s'>\n", tok);
+ xml = g_string_append(xml, markup);
+ g_free(markup);
+ num_menus++;
+ }
}
- gtk_ui_manager_insert_action_group (ui_manager_main_menubar, action_group, 0);
+ /* Use the last path element as the name of the menu item. Allow blank
+ * menu name or else the menu is hidden (and thus useless). Showing a
+ * blank menu allows the developer to see the problem and fix it.
+ */
+ if ( (tok != NULL) /* && (tok[0] != '\0') */ ) {
+ if (g_strcmp0(tok, "-") == 0) {
+ xml = g_string_append(xml, "<separator/>\n");
+ } else {
+ /* strip label from token...it's used later in menu actions */
+ lbl = strchr(tok, '|');
+ if (lbl != NULL) *lbl++ = '\0';
+
+ /* append self-closing menu-item tag */
+ markup = g_markup_printf_escaped("<menuitem action='%s'/>\n", tok);
+ xml = g_string_append(xml, markup);
+ g_free(markup);
+ }
+ }
- while(merge_lua_menu_items_list != NULL) {
- menu_item_data = merge_lua_menu_items_list->data;
- action_name = g_strdup_printf ("LUA-menuitem-%u", i);
- /*g_warning("action_name %s, filter_entry->name %s",action_name,filter_entry->name);*/
- action = g_object_new (GTK_TYPE_ACTION,
- "name", action_name,
- "label", menu_item_data->label,
- "stock-id", menu_item_data->stock_id,
- "tooltip", menu_item_data->tooltip,
- "sensitive", menu_item_data->enabled,
- NULL);
- g_signal_connect (action, "activate",
- G_CALLBACK (menu_item_data->callback), menu_item_data->callback_data);
+ /* we just processed the last token, so free the list */
+ g_strfreev(tokens);
+
+ /* close all menu tags, and then append the footer */
+ for (; num_menus > 0; num_menus--) {
+ xml = g_string_append(xml, "</menu>");
+ }
+ xml = g_string_append(xml, XMENU_FOOTER);
+
+ /* free the GString object, return the allocated char buf which must be g_freed */
+ markup = g_string_free(xml, FALSE);
+ /* printf("Lua Menu XML:\n%s\n", markup); */
+
+ return markup;
+}
+
+/**
+ * Creates an action group for the menu items in xpath, and returns it. The caller should
+ * use g_object_unref() on the returned pointer if transferring scope.
+ */
+static GtkActionGroup*
+make_menu_actions(const char *path, const menu_item_t *menu_item_data) {
+ GtkActionGroup *action_group;
+ GtkAction *action;
+ char **p;
+ char **tokens;
+ char *lbl;
+ const char *tok = path;
+
+ action_group = gtk_action_group_new (path);
+
+ tokens = g_strsplit(path, "/", XMENU_MAX_DEPTH);
+ for (p = tokens; (p != NULL) && (*p != NULL); p++) {
+
+ tok = g_strstrip(*p);
+
+ if (tok[0] == '\0') continue;
+
+ /* reserve last token for item name */
+ if ( *(p+1) == NULL ) break;
+
+ if (g_strcmp0(tok, "-") != 0) {
+
+ /* parse label from token */
+ lbl = strchr(tok, '|');
+ if (lbl != NULL) {
+ *lbl++ = '\0';
+ }
+ if ((lbl == NULL) || (*lbl == '\0')) {
+ lbl = (char*)tok;
+ }
+
+ action = g_object_new (
+ GTK_TYPE_ACTION,
+ "name", tok,
+ "label", lbl,
+ NULL
+ );
+ gtk_action_group_add_action (action_group, action);
+ g_object_unref (action);
+ }
+ }
+
+ /* handle menu item (blank names ok) */
+ if ( (tok != NULL) /* && (tok[0] != '\0') */ && (menu_item_data != NULL) ) {
+
+ /* parse label from token */
+ lbl = strchr(tok, '|');
+ if (lbl != NULL) {
+ *lbl++ = '\0';
+ }
+ if ((lbl == NULL) || (*lbl == '\0')) {
+ lbl = (char*)tok;
+ }
+
+ action = g_object_new (
+ GTK_TYPE_ACTION,
+ "name", tok,
+ "label", lbl,
+ "stock-id", menu_item_data->stock_id,
+ "tooltip", menu_item_data->tooltip,
+ "sensitive", menu_item_data->enabled,
+ NULL
+ );
+ if (menu_item_data->callback != NULL) {
+ g_signal_connect (
+ action,
+ "activate",
+ G_CALLBACK (menu_item_data->callback),
+ menu_item_data->callback_data
+ );
+ }
gtk_action_group_add_action (action_group, action);
g_object_unref (action);
+ }
- gtk_ui_manager_add_ui (ui_manager_main_menubar, merge_id,
- "/Menubar/ToolsMenu/LUA/LUA-menu-items",
- action_name,
- action_name,
- GTK_UI_MANAGER_MENUITEM,
- FALSE);
- i++;
+ /* we just processed the last token, so free the list */
+ g_strfreev(tokens);
+
+ return action_group;
+}
+
+static void
+merge_lua_menu_items(GList *merge_lua_menu_items_list _U_)
+{
+#ifdef HAVE_LUA_5_1
+ guint merge_id;
+ GtkActionGroup *action_group;
+ menu_item_t *menu_item_data;
+ GError *err;
+ const gchar *xml;
+ gchar *xpath;
+
+ while(merge_lua_menu_items_list != NULL) {
+ menu_item_data = merge_lua_menu_items_list->data;
+ xpath = g_strdup_printf("%s/%s", menu_item_data->gui_path, menu_item_data->name);
+
+ xml = make_menu_xml(xpath);
+ if (xml != NULL) {
+
+ /* create action group for menu elements */
+ action_group = make_menu_actions(xpath, menu_item_data);
+ gtk_ui_manager_insert_action_group (ui_manager_main_menubar, action_group, 0);
+
+ /* add menu elements to menu bar */
+ err = NULL;
+ merge_id = gtk_ui_manager_add_ui_from_string (ui_manager_main_menubar, xml, -1, &err);
+ if (err != NULL) {
+ fprintf (stderr, "Warning: building Lua menus failed: %s\n",
+ err->message);
+ g_error_free (err);
+
+ /* undo the mess */
+ gtk_ui_manager_remove_ui (ui_manager_main_menubar, merge_id);
+ gtk_ui_manager_remove_action_group (ui_manager_main_menubar, action_group);
+ }
+ g_free ((gchar*)xml);
+ g_object_unref (action_group);
+ }
+
+ g_free(xpath);
merge_lua_menu_items_list = g_list_next(merge_lua_menu_items_list);
}
#endif