4 * $Id: menu.c,v 1.119 2003/12/03 09:28:25 guy Exp $
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@ethereal.com>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
35 #include <epan/packet.h>
36 #include <epan/resolv.h>
38 #include "capture_dlg.h"
39 #include "color_dlg.h"
40 #include "filter_prefs.h"
44 #include "summary_dlg.h"
45 #include "display_opts.h"
46 #include "prefs_dlg.h"
47 #include "packet_win.h"
49 #include "follow_dlg.h"
50 #include "decode_as_dlg.h"
52 #include "supported_protos_dlg.h"
53 #include "proto_dlg.h"
54 #include "proto_hier_stats_dlg.h"
56 #include <epan/plugins.h>
57 #include "tcp_graph.h"
58 #include <epan/epan_dissect.h>
59 #include "compat_macros.h"
61 #include "gtkglobals.h"
65 #include "../ipproto.h"
67 GtkWidget *popup_menu_object;
69 extern void savehex_cb(GtkWidget * w, gpointer data _U_);
71 #define GTK_MENU_FUNC(a) ((GtkItemFactoryCallback)(a))
73 static void menus_init(void);
74 static void set_menu_sensitivity (GtkItemFactory *, gchar *, gint);
76 /* This is the GtkItemFactoryEntry structure used to generate new menus.
77 Item 1: The menu path. The letter after the underscore indicates an
78 accelerator key once the menu is open.
79 Item 2: The accelerator key for the entry
80 Item 3: The callback function.
81 Item 4: The callback action. This changes the parameters with
82 which the function is called. The default is 0.
83 Item 5: The item type, used to define what kind of an item it is.
84 Here are the possible values:
88 "<Title>" -> create a title item
89 "<Item>" -> create a simple item
90 "<ImageItem>" -> create an item holding an image (gtk2)
91 "<StockItem>" -> create an item holding a stock image (gtk2)
92 "<CheckItem>" -> create a check item
93 "<ToggleItem>" -> create a toggle item
94 "<RadioItem>" -> create a radio item
95 <path> -> path of a radio item to link against
96 "<Separator>" -> create a separator
97 "<Tearoff>" -> create a tearoff separator (gtk2)
98 "<Branch>" -> create an item to hold sub items (optional)
99 "<LastBranch>" -> create a right justified branch
100 Item 6: extra data needed for ImageItem and StockItem (gtk2)
104 static GtkItemFactoryEntry menu_items[] =
106 ITEM_FACTORY_ENTRY("/_File", NULL, NULL, 0, "<Branch>", NULL),
107 ITEM_FACTORY_STOCK_ENTRY("/File/_Open...", "<control>O", file_open_cmd_cb,
109 ITEM_FACTORY_STOCK_ENTRY("/File/_Close", "<control>W", file_close_cmd_cb,
111 ITEM_FACTORY_ENTRY("/File/<separator>", NULL, NULL, 0, "<Separator>", NULL),
112 ITEM_FACTORY_STOCK_ENTRY("/File/_Save", "<control>S", file_save_cmd_cb,
114 ITEM_FACTORY_STOCK_ENTRY("/File/Save _As...", "<shift><control>S", file_save_as_cmd_cb,
115 0, GTK_STOCK_SAVE_AS),
116 ITEM_FACTORY_STOCK_ENTRY("/File/Save _Highlighted...", "<control>H", savehex_cb,
118 ITEM_FACTORY_ENTRY("/File/<separator>", NULL, NULL, 0, "<Separator>", NULL),
119 ITEM_FACTORY_STOCK_ENTRY("/File/_Print...", "<control>P", file_print_cmd_cb,
121 ITEM_FACTORY_ENTRY("/File/<separator>", NULL, NULL, 0, "<Separator>", NULL),
122 ITEM_FACTORY_ENTRY("/File/Print Pac_ket", NULL,
123 file_print_packet_cmd_cb, 0, NULL, NULL),
124 ITEM_FACTORY_ENTRY("/File/<separator>", NULL, NULL, 0, "<Separator>", NULL),
125 ITEM_FACTORY_STOCK_ENTRY("/File/_Quit", "<control>Q", file_quit_cmd_cb,
127 ITEM_FACTORY_ENTRY("/_Edit", NULL, NULL, 0, "<Branch>", NULL),
129 /* Un-#if this when we actually implement Cut/Copy/Paste. */
130 ITEM_FACTORY_STOCK_ENTRY("/Edit/Cut", "<control>X", NULL,
132 ITEM_FACTORY_STOCK_ENTRY("/Edit/Copy", "<control>C", NULL,
134 ITEM_FACTORY_STOCK_ENTRY("/Edit/Paste", "<control>V", NULL,
136 ITEM_FACTORY_ENTRY("/Edit/<separator>", NULL, NULL, 0, "<Separator>"),
138 ITEM_FACTORY_STOCK_ENTRY("/Edit/_Find Packet...", "<control>F",
139 find_frame_cb, 0, GTK_STOCK_FIND),
140 ITEM_FACTORY_STOCK_ENTRY("/Edit/Find Ne_xt", "<control>N", find_next_cb,
141 0, GTK_STOCK_GO_FORWARD),
142 ITEM_FACTORY_STOCK_ENTRY("/Edit/Find Pre_vious", "<control>B",
143 find_previous_cb, 0, GTK_STOCK_GO_BACK),
144 ITEM_FACTORY_ENTRY("/Edit/<separator>", NULL, NULL, 0, "<Separator>", NULL),
145 ITEM_FACTORY_STOCK_ENTRY("/Edit/_Go To Packet...", "<control>G",
146 goto_frame_cb, 0, GTK_STOCK_JUMP_TO),
147 ITEM_FACTORY_ENTRY("/Edit/Go To _Corresponding Packet", NULL, goto_framenum_cb,
149 ITEM_FACTORY_ENTRY("/Edit/<separator>", NULL, NULL, 0, "<Separator>", NULL),
150 ITEM_FACTORY_ENTRY("/Edit/Time _Reference", NULL, NULL, 0, "<Branch>", NULL),
151 ITEM_FACTORY_ENTRY("/Edit/Time Reference/Set Time Reference (toggle)", "<control>T", reftime_frame_cb, 0, NULL, NULL),
152 ITEM_FACTORY_ENTRY("/Edit/Time Reference/Find Next", NULL, reftime_frame_cb, 1, NULL, NULL),
153 ITEM_FACTORY_ENTRY("/Edit/Time Reference/Find Previous", NULL, reftime_frame_cb, 2, NULL, NULL),
154 ITEM_FACTORY_ENTRY("/Edit/_Mark Packet", "<control>M", mark_frame_cb,
156 ITEM_FACTORY_ENTRY("/Edit/Mark _All Packets", NULL, mark_all_frames_cb,
158 ITEM_FACTORY_ENTRY("/Edit/_Unmark All Packets", NULL, unmark_all_frames_cb,
160 ITEM_FACTORY_ENTRY("/Edit/<separator>", NULL, NULL, 0, "<Separator>", NULL),
161 ITEM_FACTORY_STOCK_ENTRY("/Edit/_Preferences...", "<shift><control>P", prefs_cb,
162 0, GTK_STOCK_PREFERENCES),
163 ITEM_FACTORY_ENTRY("/_View", NULL, NULL, 0, "<Branch>", NULL),
165 /* XXX: the show/hide functionality of the GUI elements is currently not implemented */
166 ITEM_FACTORY_ENTRY("/View/_Show", NULL, NULL, 0, "<Branch>", NULL),
167 ITEM_FACTORY_ENTRY("/View/_Show/Main Toolbar", NULL, NULL, 0, "<CheckItem>", NULL),
168 ITEM_FACTORY_ENTRY("/View/_Show/Filter Toolbar", NULL, NULL, 0, "<CheckItem>", NULL),
169 ITEM_FACTORY_ENTRY("/View/_Show/Status Bar", NULL, NULL, 0, "<CheckItem>", NULL),
170 ITEM_FACTORY_ENTRY("/View/_Show/Packet List", NULL, NULL, 0, "<CheckItem>", NULL),
171 ITEM_FACTORY_ENTRY("/View/_Show/Packet Dissection", NULL, NULL, 0, "<CheckItem>", NULL),
172 ITEM_FACTORY_ENTRY("/View/_Show/Packet Data", NULL, NULL, 0, "<CheckItem>", NULL),
173 /* XXX: the settings in the "Options" dialog could be seperated into the following menu items. */
174 /* before this, some effort must be taken to transfer the functionality of this dialog to the menu items */
175 /* (getting the current values, handling the radioitems, ...) */
176 ITEM_FACTORY_ENTRY("/View/_Time Display Format", NULL, NULL, 0, "<Branch>", NULL),
177 ITEM_FACTORY_ENTRY("/View/_Time Display Format/Time of day", NULL, NULL, 0, "<RadioItem>", NULL),
178 ITEM_FACTORY_ENTRY("/View/_Time Display Format/Date and time of day", NULL, NULL, 0, "<RadioItem>", NULL),
179 ITEM_FACTORY_ENTRY("/View/_Time Display Format/Seconds since beginning of capture", NULL, NULL, 0, "<RadioItem>", NULL),
180 ITEM_FACTORY_ENTRY("/View/_Time Display Format/Seconds since previous capture", NULL, NULL, 0, "<RadioItem>", NULL),
181 ITEM_FACTORY_ENTRY("/View/_Name Resolution", NULL, NULL, 0, "<Branch>", NULL),
182 ITEM_FACTORY_ENTRY("/View/_Name Resolution/Enable MAC", NULL, NULL, 0, "<CheckItem>", NULL),
183 ITEM_FACTORY_ENTRY("/View/_Name Resolution/Enable Network", NULL, NULL, 0, "<CheckItem>", NULL),
184 ITEM_FACTORY_ENTRY("/View/_Name Resolution/Enable Transport", NULL, NULL, 0, "<CheckItem>", NULL),
186 ITEM_FACTORY_ENTRY("/View/_Options...", NULL, display_opt_cb,
189 ITEM_FACTORY_ENTRY("/View/<separator>", NULL, NULL, 0, "<Separator>", NULL),
190 ITEM_FACTORY_ENTRY("/View/Collapse _All", NULL, collapse_all_cb,
192 ITEM_FACTORY_ENTRY("/View/_Expand All", NULL, expand_all_cb,
194 ITEM_FACTORY_ENTRY("/View/<separator>", NULL, NULL, 0, "<Separator>", NULL),
195 ITEM_FACTORY_STOCK_ENTRY("/View/_Coloring Rules...", NULL, color_display_cb,
196 0, GTK_STOCK_SELECT_COLOR),
197 ITEM_FACTORY_ENTRY("/View/<separator>", NULL, NULL, 0, "<Separator>", NULL),
198 ITEM_FACTORY_ENTRY("/View/_Show Packet In New Window", NULL,
199 new_window_cb, 0, NULL, NULL),
200 ITEM_FACTORY_STOCK_ENTRY("/View/_Reload", "<control>R", file_reload_cmd_cb,
201 0, GTK_STOCK_REFRESH),
203 ITEM_FACTORY_ENTRY("/_Capture", NULL, NULL, 0, "<Branch>", NULL),
204 ITEM_FACTORY_STOCK_ENTRY("/Capture/_Start...", "<control>K",
205 capture_prep_cb, 0, ETHEREAL_STOCK_CAPTURE_START),
207 * XXX - this doesn't yet work in Win32.
210 ITEM_FACTORY_STOCK_ENTRY("/Capture/S_top", "<control>E", capture_stop_cb,
213 ITEM_FACTORY_STOCK_ENTRY("/Capture/_Capture Filters...", NULL, cfilter_dialog_cb,
214 0, ETHEREAL_STOCK_CAPTURE_FILTER),
215 #endif /* HAVE_LIBPCAP */
216 ITEM_FACTORY_ENTRY("/_Analyze", NULL, NULL, 0, "<Branch>", NULL),
217 ITEM_FACTORY_STOCK_ENTRY("/Analyze/_Display Filters...", NULL, dfilter_dialog_cb,
218 0, ETHEREAL_STOCK_DISPLAY_FILTER),
219 ITEM_FACTORY_ENTRY("/Analyze/_Match", NULL, NULL, 0, "<Branch>", NULL),
220 ITEM_FACTORY_ENTRY("/Analyze/Match/_Selected", NULL,
221 match_selected_cb_replace_ptree, 0, NULL, NULL),
222 ITEM_FACTORY_ENTRY("/Analyze/Match/_Not Selected", NULL,
223 match_selected_cb_not_ptree, 0, NULL, NULL),
224 ITEM_FACTORY_ENTRY("/Analyze/Match/_And Selected", NULL,
225 match_selected_cb_and_ptree, 0, NULL, NULL),
226 ITEM_FACTORY_ENTRY("/Analyze/Match/_Or Selected", NULL,
227 match_selected_cb_or_ptree, 0, NULL, NULL),
228 ITEM_FACTORY_ENTRY("/Analyze/Match/A_nd Not Selected", NULL,
229 match_selected_cb_and_ptree_not, 0, NULL, NULL),
230 ITEM_FACTORY_ENTRY("/Analyze/Match/O_r Not Selected", NULL,
231 match_selected_cb_or_ptree_not, 0, NULL, NULL),
232 ITEM_FACTORY_ENTRY("/Analyze/_Prepare", NULL, NULL, 0, "<Branch>", NULL),
233 ITEM_FACTORY_ENTRY("/Analyze/Prepare/_Selected", NULL,
234 prepare_selected_cb_replace_ptree, 0, NULL, NULL),
235 ITEM_FACTORY_ENTRY("/Analyze/Prepare/_Not Selected", NULL,
236 prepare_selected_cb_not_ptree, 0, NULL, NULL),
237 ITEM_FACTORY_ENTRY("/Analyze/Prepare/_And Selected", NULL,
238 prepare_selected_cb_and_ptree, 0, NULL, NULL),
239 ITEM_FACTORY_ENTRY("/Analyze/Prepare/_Or Selected", NULL,
240 prepare_selected_cb_or_ptree, 0, NULL, NULL),
241 ITEM_FACTORY_ENTRY("/Analyze/Prepare/A_nd Not Selected", NULL,
242 prepare_selected_cb_and_ptree_not, 0, NULL, NULL),
243 ITEM_FACTORY_ENTRY("/Analyze/Prepare/O_r Not Selected", NULL,
244 prepare_selected_cb_or_ptree_not, 0, NULL, NULL),
245 ITEM_FACTORY_ENTRY("/Analyze/<separator>", NULL, NULL, 0, "<Separator>", NULL),
246 ITEM_FACTORY_ENTRY("/Analyze/_Enabled Protocols...", "<shift><control>R", proto_cb, 0, NULL, NULL),
247 ITEM_FACTORY_ENTRY("/Analyze/Decode _As...", NULL, decode_as_cb,
249 ITEM_FACTORY_ENTRY("/Analyze/_User Specified Decodes", NULL,
250 decode_show_cb, 0, NULL, NULL),
251 ITEM_FACTORY_ENTRY("/Analyze/<separator>", NULL, NULL, 0, "<Separator>", NULL),
252 ITEM_FACTORY_ENTRY("/Analyze/_Follow TCP Stream", NULL, follow_stream_cb,
254 /* {"/Analyze/Graph", NULL, NULL, 0, NULL}, future use */
255 ITEM_FACTORY_ENTRY("/Analyze/_TCP Stream Analysis", NULL, NULL,
256 0, "<Branch>", NULL),
257 ITEM_FACTORY_ENTRY("/Analyze/TCP Stream Analysis/Time-Sequence Graph (Stevens)",
258 NULL, tcp_graph_cb, 0, NULL, NULL),
259 ITEM_FACTORY_ENTRY("/Analyze/TCP Stream Analysis/Time-Sequence Graph (tcptrace)",
260 NULL, tcp_graph_cb, 1, NULL, NULL),
261 ITEM_FACTORY_ENTRY("/Analyze/TCP Stream Analysis/Throughput Graph", NULL,
262 tcp_graph_cb, 2, NULL, NULL),
263 ITEM_FACTORY_ENTRY("/Analyze/TCP Stream Analysis/RTT Graph", NULL,
264 tcp_graph_cb, 3, NULL, NULL),
265 ITEM_FACTORY_ENTRY("/Analyze/<separator>", NULL, NULL, 0, "<Separator>", NULL),
266 ITEM_FACTORY_ENTRY("/Analyze/_Summary", NULL, summary_open_cb, 0, NULL, NULL),
267 ITEM_FACTORY_ENTRY("/Analyze/Protocol _Hierarchy Statistics", NULL,
268 proto_hier_stats_cb, 0, NULL, NULL),
269 ITEM_FACTORY_ENTRY("/_Help", NULL, NULL, 0, "<Branch>", NULL),
270 ITEM_FACTORY_STOCK_ENTRY("/Help/_Contents", "F1", help_cb, 0, GTK_STOCK_HELP),
271 ITEM_FACTORY_ENTRY("/Help/_Supported Protocols", NULL, supported_cb, 0, NULL, NULL),
272 ITEM_FACTORY_ENTRY("/Help/<separator>", NULL, NULL, 0, "<Separator>", NULL),
274 ITEM_FACTORY_ENTRY("/Help/About _Plugins", NULL, tools_plugins_cmd_cb,
276 #endif /* HAVE_PLUGINS */
277 ITEM_FACTORY_ENTRY("/Help/_About Ethereal", NULL, about_ethereal,
282 /* calculate the number of menu_items */
283 static int nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
285 /* packet list popup */
286 static GtkItemFactoryEntry packet_list_menu_items[] =
288 ITEM_FACTORY_ENTRY("/Follow TCP Stream", NULL, follow_stream_cb,
290 ITEM_FACTORY_ENTRY("/Decode As...", NULL, decode_as_cb, 0, NULL, NULL),
291 ITEM_FACTORY_ENTRY("/Display Filters...", NULL, dfilter_dialog_cb,
293 ITEM_FACTORY_ENTRY("/<separator>", NULL, NULL, 0, "<Separator>", NULL),
294 ITEM_FACTORY_ENTRY("/Mark Packet", NULL, mark_frame_cb, 0, NULL, NULL),
295 ITEM_FACTORY_ENTRY("/Time Reference", NULL, NULL, 0, "<Branch>", NULL),
296 ITEM_FACTORY_ENTRY("/Time Reference/Set Time Reference (toggle)", NULL, reftime_frame_cb, 0, NULL, NULL),
297 ITEM_FACTORY_ENTRY("/Time Reference/Find Next", NULL, reftime_frame_cb, 1, NULL, NULL),
298 ITEM_FACTORY_ENTRY("/Time Reference/Find Previous", NULL, reftime_frame_cb, 2, NULL, NULL),
299 ITEM_FACTORY_ENTRY("/Match", NULL, NULL, 0, "<Branch>", NULL),
300 ITEM_FACTORY_ENTRY("/Match/_Selected", NULL,
301 match_selected_cb_replace_plist, 0, NULL, NULL),
302 ITEM_FACTORY_ENTRY("/Match/_Not Selected", NULL,
303 match_selected_cb_not_plist, 0, NULL, NULL),
304 ITEM_FACTORY_ENTRY("/Match/_And Selected", NULL,
305 match_selected_cb_and_plist, 0, NULL, NULL),
306 ITEM_FACTORY_ENTRY("/Match/_Or Selected", NULL, match_selected_cb_or_plist,
308 ITEM_FACTORY_ENTRY("/Match/A_nd Not Selected", NULL,
309 match_selected_cb_and_plist_not, 0, NULL, NULL),
310 ITEM_FACTORY_ENTRY("/Match/O_r Not Selected", NULL,
311 match_selected_cb_or_plist_not, 0, NULL, NULL),
312 ITEM_FACTORY_ENTRY("/Prepare", NULL, NULL, 0, "<Branch>", NULL),
313 ITEM_FACTORY_ENTRY("/Prepare/_Selected", NULL,
314 prepare_selected_cb_replace_plist, 0, NULL, NULL),
315 ITEM_FACTORY_ENTRY("/Prepare/_Not Selected", NULL,
316 prepare_selected_cb_not_plist, 0, NULL, NULL),
317 ITEM_FACTORY_ENTRY("/Prepare/_And Selected", NULL,
318 prepare_selected_cb_and_plist, 0, NULL, NULL),
319 ITEM_FACTORY_ENTRY("/Prepare/_Or Selected", NULL,
320 prepare_selected_cb_or_plist, 0, NULL, NULL),
321 ITEM_FACTORY_ENTRY("/Prepare/A_nd Not Selected", NULL,
322 prepare_selected_cb_and_plist_not, 0, NULL, NULL),
323 ITEM_FACTORY_ENTRY("/Prepare/O_r Not Selected", NULL,
324 prepare_selected_cb_or_plist_not, 0, NULL, NULL),
325 ITEM_FACTORY_ENTRY("/<separator>", NULL, NULL, 0, "<Separator>", NULL),
326 ITEM_FACTORY_ENTRY("/Coloring Rules...", NULL, color_display_cb,
328 ITEM_FACTORY_ENTRY("/Print...", NULL, file_print_cmd_cb, 0, NULL, NULL),
329 ITEM_FACTORY_ENTRY("/Print Packet", NULL, file_print_packet_cmd_cb,
331 ITEM_FACTORY_ENTRY("/Show Packet In New Window", NULL, new_window_cb,
335 static GtkItemFactoryEntry tree_view_menu_items[] =
337 ITEM_FACTORY_ENTRY("/Follow TCP Stream", NULL, follow_stream_cb,
339 ITEM_FACTORY_ENTRY("/Decode As...", NULL, decode_as_cb, 0, NULL, NULL),
340 ITEM_FACTORY_ENTRY("/Display Filters...", NULL, dfilter_dialog_cb,
342 ITEM_FACTORY_ENTRY("/<separator>", NULL, NULL, 0, "<Separator>", NULL),
343 ITEM_FACTORY_ENTRY("/_Resolve Name", NULL, resolve_name_cb, 0, NULL, NULL),
344 ITEM_FACTORY_ENTRY("/_Go To Corresponding Packet", NULL, goto_framenum_cb, 0, NULL, NULL),
345 ITEM_FACTORY_ENTRY("/Protocol Properties...", NULL, properties_cb,
347 ITEM_FACTORY_ENTRY("/Match", NULL, NULL, 0, "<Branch>", NULL),
348 ITEM_FACTORY_ENTRY("/Match/_Selected", NULL,
349 match_selected_cb_replace_ptree, 0, NULL, NULL),
350 ITEM_FACTORY_ENTRY("/Match/_Not Selected", NULL,
351 match_selected_cb_not_ptree, 0, NULL, NULL),
352 ITEM_FACTORY_ENTRY("/Match/_And Selected", NULL,
353 match_selected_cb_and_ptree, 0, NULL, NULL),
354 ITEM_FACTORY_ENTRY("/Match/_Or Selected", NULL, match_selected_cb_or_ptree,
356 ITEM_FACTORY_ENTRY("/Match/A_nd Not Selected", NULL,
357 match_selected_cb_and_ptree_not, 0, NULL, NULL),
358 ITEM_FACTORY_ENTRY("/Match/O_r Not Selected", NULL,
359 match_selected_cb_or_ptree_not, 0, NULL, NULL),
360 ITEM_FACTORY_ENTRY("/Prepare", NULL, NULL, 0, "<Branch>", NULL),
361 ITEM_FACTORY_ENTRY("/Prepare/_Selected", NULL,
362 prepare_selected_cb_replace_ptree, 0, NULL, NULL),
363 ITEM_FACTORY_ENTRY("/Prepare/_Not Selected", NULL,
364 prepare_selected_cb_not_ptree, 0, NULL, NULL),
365 ITEM_FACTORY_ENTRY("/Prepare/_And Selected", NULL,
366 prepare_selected_cb_and_ptree, 0, NULL, NULL),
367 ITEM_FACTORY_ENTRY("/Prepare/_Or Selected", NULL,
368 prepare_selected_cb_or_ptree, 0, NULL, NULL),
369 ITEM_FACTORY_ENTRY("/Prepare/A_nd Not Selected", NULL,
370 prepare_selected_cb_and_ptree_not, 0, NULL, NULL),
371 ITEM_FACTORY_ENTRY("/Prepare/O_r Not Selected", NULL,
372 prepare_selected_cb_or_ptree_not, 0, NULL, NULL),
373 ITEM_FACTORY_ENTRY("/<separator>", NULL, NULL, 0, "<Separator>", NULL),
374 ITEM_FACTORY_ENTRY("/Collapse All", NULL, collapse_all_cb, 0, NULL, NULL),
375 ITEM_FACTORY_ENTRY("/Expand All", NULL, expand_all_cb, 0, NULL, NULL)
378 static GtkItemFactoryEntry hexdump_menu_items[] =
380 ITEM_FACTORY_ENTRY("/Follow TCP Stream", NULL, follow_stream_cb,
382 ITEM_FACTORY_ENTRY("/Decode As...", NULL, decode_as_cb, 0, NULL, NULL),
383 ITEM_FACTORY_ENTRY("/Display Filters...", NULL, dfilter_dialog_cb,
385 ITEM_FACTORY_ENTRY("/Save Highlighted Data...", NULL, savehex_cb,
389 static int initialize = TRUE;
390 static GtkItemFactory *main_menu_factory = NULL;
391 static GtkItemFactory *packet_list_menu_factory = NULL;
392 static GtkItemFactory *tree_view_menu_factory = NULL;
393 static GtkItemFactory *hexdump_menu_factory = NULL;
395 static GSList *popup_menu_list = NULL;
397 static GtkAccelGroup *grp;
400 get_main_menu(GtkWidget ** menubar, GtkAccelGroup ** table) {
402 grp = gtk_accel_group_new();
408 *menubar = main_menu_factory->widget;
421 packet_list_menu_factory = gtk_item_factory_new(GTK_TYPE_MENU, "<main>", NULL);
422 popup_menu_object = gtk_menu_new();
423 gtk_item_factory_create_items_ac(packet_list_menu_factory, sizeof(packet_list_menu_items)/sizeof(packet_list_menu_items[0]), packet_list_menu_items, popup_menu_object, 2);
424 OBJECT_SET_DATA(popup_menu_object, PM_PACKET_LIST_KEY,
425 packet_list_menu_factory->widget);
426 popup_menu_list = g_slist_append((GSList *)popup_menu_list, packet_list_menu_factory);
428 tree_view_menu_factory = gtk_item_factory_new(GTK_TYPE_MENU, "<main>", NULL);
429 gtk_item_factory_create_items_ac(tree_view_menu_factory, sizeof(tree_view_menu_items)/sizeof(tree_view_menu_items[0]), tree_view_menu_items, popup_menu_object, 2);
430 OBJECT_SET_DATA(popup_menu_object, PM_TREE_VIEW_KEY,
431 tree_view_menu_factory->widget);
432 popup_menu_list = g_slist_append((GSList *)popup_menu_list, tree_view_menu_factory);
434 hexdump_menu_factory = gtk_item_factory_new(GTK_TYPE_MENU, "<main>", NULL);
435 gtk_item_factory_create_items_ac(hexdump_menu_factory, sizeof(hexdump_menu_items)/sizeof(hexdump_menu_items[0]), hexdump_menu_items, popup_menu_object, 2);
436 OBJECT_SET_DATA(popup_menu_object, PM_HEXDUMP_KEY,
437 hexdump_menu_factory->widget);
438 popup_menu_list = g_slist_append((GSList *)popup_menu_list, hexdump_menu_factory);
441 main_menu_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", grp);
442 gtk_item_factory_create_items_ac(main_menu_factory, nmenu_items, menu_items, NULL,2);
443 register_all_tap_menus(); /* must be done after creating the main menu */
445 /* Initialize enabled/disabled state of menu items */
446 set_menus_for_unsaved_capture_file(FALSE);
447 set_menus_for_capture_file(FALSE);
449 /* Un-#if this when we actually implement Cut/Copy/Paste.
450 Then make sure you enable them when they can be done. */
451 set_menu_sensitivity(main_menu_factory, "/Edit/Cut", FALSE);
452 set_menu_sensitivity(main_menu_factory, "/Edit/Copy", FALSE);
453 set_menu_sensitivity(main_menu_factory, "/Edit/Paste", FALSE);
456 set_menus_for_captured_packets(FALSE);
457 set_menus_for_selected_packet(&cfile);
458 set_menus_for_selected_tree_row(&cfile);
462 typedef struct _menu_item {
465 gboolean (*selected_packet_enabled)(frame_data *, epan_dissect_t *);
466 gboolean (*selected_tree_row_enabled)(field_info *);
467 struct _menu_item *parent;
468 struct _menu_item *children;
469 struct _menu_item *next;
472 static menu_item_t tap_menu_tree_root;
475 * Add a new menu item for a tap.
476 * This must be called after we've created the main menu, so it can't
477 * be called from the routine that registers taps - we have to introduce
478 * another per-tap registration routine.
480 * "callback" gets called when the menu item is selected; it should do
481 * the work of creating the tap window.
483 * "selected_packet_enabled" gets called by "set_menus_for_selected_packet()";
484 * it's passed a Boolean that's TRUE if a packet is selected and FALSE
485 * otherwise, and should return TRUE if the tap will work now (which
486 * might depend on whether a packet is selected and, if one is, on the
487 * packet) and FALSE if not.
489 * "selected_tree_row_enabled" gets called by
490 * "set_menus_for_selected_tree_row()"; it's passed a Boolean that's TRUE if
491 * a protocol tree row is selected and FALSE otherwise, and should return
492 * TRUE if the tap will work now (which might depend on whether a tree row
493 * is selected and, if one is, on the tree row) and FALSE if not.
496 register_tap_menu_item(char *name, GtkItemFactoryCallback callback,
497 gboolean (*selected_packet_enabled)(frame_data *, epan_dissect_t *),
498 gboolean (*selected_tree_row_enabled)(field_info *))
500 static const char toolspath[] = "/Analyze/";
504 GtkItemFactoryEntry *entry;
505 menu_item_t *curnode, *child;
508 * The menu path must be relative.
510 g_assert(*name != '/');
513 * Create any submenus required.
515 curnode = &tap_menu_tree_root;
517 while ((p = strchr(p, '/')) != NULL) {
519 * OK, everything between "name" and "p" is
520 * a menu relative subtree into which the menu item
523 * Construct the absolute path name of that subtree.
525 menupathlen = sizeof toolspath + (p - name);
526 menupath = g_malloc(menupathlen);
527 strcpy(menupath, toolspath);
528 strncat(menupath, name, p - name);
531 * Does there exist an entry with that path at this
532 * level of the Tools menu tree?
534 for (child = curnode->children; child != NULL;
535 child = child->next) {
536 if (strcmp(child->name, menupath) == 0)
541 * No. Create such an item as a subtree, and
542 * add it to the Tools menu tree.
544 entry = g_malloc0(sizeof (GtkItemFactoryEntry));
545 entry->path = menupath;
546 entry->item_type = "<Branch>";
547 gtk_item_factory_create_item(main_menu_factory, entry,
549 set_menu_sensitivity(main_menu_factory, menupath,
550 FALSE); /* no children yet */
551 child = g_malloc(sizeof (menu_item_t));
552 child->name = menupath;
553 child->selected_packet_enabled = NULL;
554 child->selected_tree_row_enabled = NULL;
555 child->enabled = FALSE; /* no children yet */
556 child->parent = curnode;
557 child->children = NULL;
558 child->next = curnode->children;
559 curnode->children = child;
562 * Yes. We don't need "menupath" any more.
569 * Skip over the '/' we found.
575 * Construct the main menu path for the menu item.
577 * "sizeof toolspath" includes the trailing '\0', so the sum
578 * of that and the length of "name" is enough to hold a string
579 * containing their concatenation.
581 menupathlen = sizeof toolspath + strlen(name);
582 menupath = g_malloc(menupathlen);
583 strcpy(menupath, toolspath);
584 strcat(menupath, name);
587 * Construct an item factory entry for the item, and add it to
590 entry = g_malloc0(sizeof (GtkItemFactoryEntry));
591 entry->path = menupath;
592 entry->callback = callback;
593 gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);
594 set_menu_sensitivity(main_menu_factory, menupath, FALSE); /* no capture file yet */
595 child = g_malloc(sizeof (menu_item_t));
596 child->name = menupath;
597 child->enabled = FALSE; /* no capture file yet, hence no taps yet */
598 child->selected_packet_enabled = selected_packet_enabled;
599 child->selected_tree_row_enabled = selected_tree_row_enabled;
600 child->parent = curnode;
601 child->children = NULL;
602 child->next = curnode->children;
603 curnode->children = child;
607 * Enable/disable menu sensitivity.
610 set_menu_sensitivity(GtkItemFactory *ifactory, gchar *path, gint val)
613 GtkWidget *menu_item;
615 if (ifactory == NULL) {
617 * Do it for all pop-up menus.
619 for (menu_list = popup_menu_list; menu_list != NULL;
620 menu_list = g_slist_next(menu_list))
621 set_menu_sensitivity(menu_list->data, path, val);
624 * Do it for that particular menu.
626 if ((menu_item = gtk_item_factory_get_widget(ifactory, path)) != NULL) {
627 if (GTK_IS_MENU(menu_item)) {
629 * "path" refers to a submenu; "gtk_item_factory_get_widget()"
630 * gets the menu, not the item that, when selected, pops up
633 * We have to change the latter item's sensitivity, so that
634 * it shows up normally if sensitive and grayed-out if
637 menu_item = gtk_menu_get_attach_widget(GTK_MENU(menu_item));
639 gtk_widget_set_sensitive(menu_item, val);
645 set_menu_object_data_meat(GtkItemFactory *ifactory, gchar *path, gchar *key, gpointer data)
647 GtkWidget *menu = NULL;
649 if ((menu = gtk_item_factory_get_widget(ifactory, path)) != NULL)
650 OBJECT_SET_DATA(menu, key, data);
654 set_menu_object_data (gchar *path, gchar *key, gpointer data) {
655 GSList *menu_list = popup_menu_list;
656 gchar *shortpath = strrchr(path, '/');
658 set_menu_object_data_meat(main_menu_factory, path, key, data);
659 while (menu_list != NULL) {
660 set_menu_object_data_meat(menu_list->data, shortpath, key, data);
661 menu_list = g_slist_next(menu_list);
666 popup_menu_handler(GtkWidget *widget, GdkEvent *event, gpointer data)
668 GtkWidget *menu = NULL;
669 GdkEventButton *event_button = NULL;
670 GtkCList *packet_list = NULL;
673 if(widget == NULL || event == NULL || data == NULL) {
678 * If we ever want to make the menu differ based on what row
679 * and/or column we're above, we'd use "gtk_clist_get_selection_info()"
680 * to find the row and column number for the coordinates; a CTree is,
681 * I guess, like a CList with one column(?) and the expander widget
684 /* Check if we are on packet_list object */
685 if (widget == OBJECT_GET_DATA(popup_menu_object, E_MPACKET_LIST_KEY)) {
686 packet_list=GTK_CLIST(widget);
687 if (gtk_clist_get_selection_info(GTK_CLIST(packet_list),
688 ((GdkEventButton *)event)->x,
689 ((GdkEventButton *)event)->y,&row,&column)) {
690 OBJECT_SET_DATA(popup_menu_object, E_MPACKET_LIST_ROW_KEY,
691 GINT_TO_POINTER(row));
692 OBJECT_SET_DATA(popup_menu_object, E_MPACKET_LIST_COL_KEY,
693 GINT_TO_POINTER(column));
696 menu = (GtkWidget *)data;
697 if(event->type == GDK_BUTTON_PRESS) {
698 event_button = (GdkEventButton *) event;
700 if(event_button->button == 3) {
701 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
702 event_button->button,
704 SIGNAL_EMIT_STOP_BY_NAME(widget, "button_press_event");
708 #if GTK_MAJOR_VERSION >= 2
709 if (widget == tree_view && event->type == GDK_2BUTTON_PRESS) {
712 if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget),
713 ((GdkEventButton *)event)->x,
714 ((GdkEventButton *)event)->y,
715 &path, NULL, NULL, NULL))
717 if (gtk_tree_view_row_expanded(GTK_TREE_VIEW(widget), path))
718 gtk_tree_view_collapse_row(GTK_TREE_VIEW(widget), path);
720 gtk_tree_view_expand_row(GTK_TREE_VIEW(widget), path,
722 gtk_tree_path_free(path);
729 /* Enable or disable menu items based on whether you have a capture file
730 you've finished reading. */
732 set_menus_for_capture_file(gboolean have_capture_file)
734 set_menu_sensitivity(main_menu_factory, "/File/Open...", have_capture_file);
735 set_menu_sensitivity(main_menu_factory, "/File/Save As...",
737 set_menu_sensitivity(main_menu_factory, "/File/Close", have_capture_file);
738 set_menu_sensitivity(main_menu_factory, "/View/Reload", have_capture_file);
739 set_toolbar_for_capture_file(have_capture_file);
742 /* Enable or disable menu items based on whether you have an unsaved
743 capture file you've finished reading. */
745 set_menus_for_unsaved_capture_file(gboolean have_unsaved_capture_file)
747 set_menu_sensitivity(main_menu_factory, "/File/Save",
748 have_unsaved_capture_file);
749 set_toolbar_for_unsaved_capture_file(have_unsaved_capture_file);
752 /* Enable or disable menu items based on whether there's a capture in
755 set_menus_for_capture_in_progress(gboolean capture_in_progress)
757 set_menu_sensitivity(main_menu_factory, "/File/Open...",
758 !capture_in_progress);
760 set_menu_sensitivity(main_menu_factory, "/Capture/Start...",
761 !capture_in_progress);
763 * XXX - this doesn't yet work in Win32.
766 set_menu_sensitivity(main_menu_factory, "/Capture/Stop",
767 capture_in_progress);
769 #endif /* HAVE_LIBPCAP */
770 set_toolbar_for_capture_in_progress(capture_in_progress);
773 /* Enable or disable menu items based on whether you have some captured
776 walk_menu_tree_for_captured_packets(menu_item_t *node,
777 gboolean have_captured_packets)
783 * Is this a leaf node or an interior node?
785 if (node->children == NULL) {
789 * If it has no "selected_packet_enabled()" or
790 * "selected_tree_row_enabled()" routines, we enable
791 * it. This allows tap windows to be popped up even
792 * if you have no capture file; this is done to let
793 * the user pop up multiple tap windows before reading
794 * in a capture file, so that they can be processed in
795 * parallel while the capture file is being read rather
796 * than one at at time as you pop up the windows, and to
797 * let the user pop up tap windows before starting an
798 * "Update list of packets in real time" capture, so that
799 * the statistics can be displayed while the capture is
802 * If it has either of those routines, we disable it for
803 * now - as long as, when a capture is first available,
804 * we don't get called after a packet or tree row is
805 * selected, that's OK.
806 * XXX - that should be done better.
808 if (node->selected_packet_enabled == NULL &&
809 node->selected_tree_row_enabled == NULL)
810 node->enabled = TRUE;
812 node->enabled = FALSE;
815 * It's an interior node; call
816 * "walk_menu_tree_for_captured_packets()" on all its
817 * children and, if any of them are enabled, enable
818 * this node, otherwise disable it.
820 * XXX - should we just leave all interior nodes enabled?
821 * Which is a better UI choice?
824 for (child = node->children; child != NULL; child =
826 if (walk_menu_tree_for_captured_packets(child,
827 have_captured_packets))
830 node->enabled = is_enabled;
834 * The root node doesn't correspond to a menu tree item; it
835 * has a null name pointer.
837 if (node->name != NULL) {
838 set_menu_sensitivity(main_menu_factory, node->name,
841 return node->enabled;
845 set_menus_for_captured_packets(gboolean have_captured_packets)
847 set_menu_sensitivity(main_menu_factory, "/File/Print...",
848 have_captured_packets);
849 set_menu_sensitivity(packet_list_menu_factory, "/Print...",
850 have_captured_packets);
851 set_menu_sensitivity(main_menu_factory, "/Edit/Find Packet...",
852 have_captured_packets);
853 set_menu_sensitivity(main_menu_factory, "/Edit/Find Next",
854 have_captured_packets);
855 set_menu_sensitivity(main_menu_factory, "/Edit/Find Previous",
856 have_captured_packets);
857 set_menu_sensitivity(main_menu_factory, "/Edit/Go To Packet...",
858 have_captured_packets);
859 set_menu_sensitivity(main_menu_factory, "/View/Coloring Rules...",
860 have_captured_packets);
861 set_menu_sensitivity(packet_list_menu_factory, "/Coloring Rules...",
862 have_captured_packets);
863 set_menu_sensitivity(main_menu_factory, "/Analyze/Summary",
864 have_captured_packets);
865 set_menu_sensitivity(main_menu_factory,
866 "/Analyze/Protocol Hierarchy Statistics", have_captured_packets);
867 set_menu_sensitivity(packet_list_menu_factory, "/Match",
868 have_captured_packets);
869 set_menu_sensitivity(packet_list_menu_factory, "/Prepare",
870 have_captured_packets);
871 walk_menu_tree_for_captured_packets(&tap_menu_tree_root,
872 have_captured_packets);
873 set_toolbar_for_captured_packets(have_captured_packets);
876 /* Enable or disable menu items based on whether a packet is selected and,
877 if so, on the properties of the packet. */
879 walk_menu_tree_for_selected_packet(menu_item_t *node, frame_data *fd,
886 * Is this a leaf node or an interior node?
888 if (node->children == NULL) {
892 * If it has no "selected_packet_enabled()" routine,
893 * leave its enabled/disabled status alone - it
894 * doesn't depend on whether we have a packet selected
895 * or not or on the selected packet.
897 * If it has a "selected_packet_enabled()" routine,
898 * call it and set the item's enabled/disabled status
899 * based on its return value.
901 if (node->selected_packet_enabled != NULL)
902 node->enabled = node->selected_packet_enabled(fd, edt);
905 * It's an interior node; call
906 * "walk_menu_tree_for_selected_packet()" on all its
907 * children and, if any of them are enabled, enable
908 * this node, otherwise disable it.
910 * XXX - should we just leave all interior nodes enabled?
911 * Which is a better UI choice?
914 for (child = node->children; child != NULL; child =
916 if (walk_menu_tree_for_selected_packet(child, fd, edt))
919 node->enabled = is_enabled;
923 * The root node doesn't correspond to a menu tree item; it
924 * has a null name pointer.
926 if (node->name != NULL) {
927 set_menu_sensitivity(main_menu_factory, node->name,
930 return node->enabled;
934 set_menus_for_selected_packet(capture_file *cf)
936 set_menu_sensitivity(main_menu_factory, "/File/Print Packet",
937 cf->current_frame != NULL);
938 set_menu_sensitivity(packet_list_menu_factory, "/Print Packet",
939 cf->current_frame != NULL);
940 set_menu_sensitivity(main_menu_factory, "/Edit/Mark Packet",
941 cf->current_frame != NULL);
942 set_menu_sensitivity(main_menu_factory, "/Edit/Time Reference",
943 cf->current_frame != NULL);
944 set_menu_sensitivity(packet_list_menu_factory, "/Mark Packet",
945 cf->current_frame != NULL);
946 set_menu_sensitivity(main_menu_factory, "/Edit/Mark All Packets",
947 cf->current_frame != NULL);
948 set_menu_sensitivity(main_menu_factory, "/Edit/Unmark All Packets",
949 cf->current_frame != NULL);
950 set_menu_sensitivity(main_menu_factory, "/View/Collapse All",
951 cf->current_frame != NULL);
952 set_menu_sensitivity(tree_view_menu_factory, "/Collapse All",
953 cf->current_frame != NULL);
954 set_menu_sensitivity(main_menu_factory, "/View/Expand All",
955 cf->current_frame != NULL);
956 set_menu_sensitivity(tree_view_menu_factory, "/Expand All",
957 cf->current_frame != NULL);
958 set_menu_sensitivity(main_menu_factory, "/View/Show Packet In New Window",
959 cf->current_frame != NULL);
960 set_menu_sensitivity(packet_list_menu_factory, "/Show Packet In New Window",
961 cf->current_frame != NULL);
962 set_menu_sensitivity(main_menu_factory, "/Analyze/Follow TCP Stream",
963 cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_TCP) : FALSE);
964 set_menu_sensitivity(NULL, "/Follow TCP Stream",
965 cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_TCP) : FALSE);
966 set_menu_sensitivity(main_menu_factory, "/Analyze/Decode As...",
967 cf->current_frame != NULL && decode_as_ok());
968 set_menu_sensitivity(NULL, "/Decode As...",
969 cf->current_frame != NULL && decode_as_ok());
970 set_menu_sensitivity(tree_view_menu_factory, "/Resolve Name",
971 cf->current_frame != NULL && g_resolv_flags == 0);
972 set_menu_sensitivity(main_menu_factory, "/Analyze/TCP Stream Analysis",
973 cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_TCP) : FALSE);
974 walk_menu_tree_for_selected_packet(&tap_menu_tree_root, cf->current_frame,
978 /* Enable or disable menu items based on whether a tree row is selected
979 and, if so, on the properties of the tree row. */
981 walk_menu_tree_for_selected_tree_row(menu_item_t *node, field_info *fi)
987 * Is this a leaf node or an interior node?
989 if (node->children == NULL) {
993 * If it has no "selected_tree_row_enabled()" routine,
994 * leave its enabled/disabled status alone - it
995 * doesn't depend on whether we have a tree row selected
996 * or not or on the selected tree row.
998 * If it has a "selected_tree_row_enabled()" routine,
999 * call it and set the item's enabled/disabled status
1000 * based on its return value.
1002 if (node->selected_tree_row_enabled != NULL)
1003 node->enabled = node->selected_tree_row_enabled(fi);
1006 * It's an interior node; call
1007 * "walk_menu_tree_for_selected_tree_row()" on all its
1008 * children and, if any of them are enabled, enable
1009 * this node, otherwise disable it.
1011 * XXX - should we just leave all interior nodes enabled?
1012 * Which is a better UI choice?
1015 for (child = node->children; child != NULL; child =
1017 if (walk_menu_tree_for_selected_tree_row(child, fi))
1020 node->enabled = is_enabled;
1024 * The root node doesn't correspond to a menu tree item; it
1025 * has a null name pointer.
1027 if (node->name != NULL) {
1028 set_menu_sensitivity(main_menu_factory, node->name,
1031 return node->enabled;
1035 set_menus_for_selected_tree_row(capture_file *cf)
1037 gboolean properties;
1039 if (cf->finfo_selected != NULL) {
1040 header_field_info *hfinfo = cf->finfo_selected->hfinfo;
1041 if (hfinfo->parent == -1) {
1042 properties = prefs_is_registered_protocol(hfinfo->abbrev);
1044 properties = prefs_is_registered_protocol(proto_registrar_get_abbrev(hfinfo->parent));
1046 set_menu_sensitivity(main_menu_factory,
1047 "/Edit/Go To Corresponding Packet", hfinfo->type == FT_FRAMENUM);
1048 set_menu_sensitivity(tree_view_menu_factory,
1049 "/Go To Corresponding Packet", hfinfo->type == FT_FRAMENUM);
1050 set_menu_sensitivity(main_menu_factory, "/Analyze/Match",
1051 proto_can_match_selected(cf->finfo_selected, cf->edt));
1052 set_menu_sensitivity(tree_view_menu_factory, "/Match",
1053 proto_can_match_selected(cf->finfo_selected, cf->edt));
1054 set_menu_sensitivity(main_menu_factory, "/Analyze/Prepare",
1055 proto_can_match_selected(cf->finfo_selected, cf->edt));
1056 set_menu_sensitivity(tree_view_menu_factory, "/Prepare",
1057 proto_can_match_selected(cf->finfo_selected, cf->edt));
1058 set_menu_sensitivity(tree_view_menu_factory, "/Protocol Properties...",
1061 set_menu_sensitivity(main_menu_factory,
1062 "/Edit/Go To Corresponding Packet", FALSE);
1063 set_menu_sensitivity(tree_view_menu_factory,
1064 "/Go To Corresponding Packet", FALSE);
1065 set_menu_sensitivity(main_menu_factory, "/Analyze/Match", FALSE);
1066 set_menu_sensitivity(tree_view_menu_factory, "/Match", FALSE);
1067 set_menu_sensitivity(main_menu_factory, "/Analyze/Prepare", FALSE);
1068 set_menu_sensitivity(tree_view_menu_factory, "/Prepare", FALSE);
1069 set_menu_sensitivity(tree_view_menu_factory, "/Protocol Properties...",
1073 walk_menu_tree_for_selected_tree_row(&tap_menu_tree_root, cf->finfo_selected);