Introduce "Ignore Packet" in the packet list.
[jlayton/wireshark.git] / gtk / menus.c
1 /* menus.c
2  * Menu routines
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
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.
14  *
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.
19  *
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.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #include <gtk/gtk.h>
30
31 #include <stdio.h>
32 #include <string.h>
33
34 #include <epan/packet.h>
35 #include <epan/addr_resolv.h>
36 #include <epan/prefs.h>
37 #include <epan/prefs-int.h>
38 #include <epan/tap.h>
39 #include <epan/timestamp.h>
40 #include <epan/etypes.h>
41 #include <epan/ipproto.h>
42 #include <epan/dissector_filters.h>
43 #include <epan/strutil.h>
44 #include <epan/plugins.h>
45 #include <epan/epan_dissect.h>
46
47 #include "../print.h"
48 #include "../register.h"
49 #include "../ui_util.h"
50 #include "../simple_dialog.h"
51 #include "../color_filters.h"
52 #include "../stat_menu.h"
53
54 #include "gtk/about_dlg.h"
55 #include "gtk/capture_dlg.h"
56 #include "gtk/capture_if_dlg.h"
57 #include "gtk/color_dlg.h"
58 #include "gtk/filter_dlg.h"
59 #include "gtk/profile_dlg.h"
60 #include "gtk/dlg_utils.h"
61 #include "gtk/capture_file_dlg.h"
62 #include "gtk/fileset_dlg.h"
63 #include "gtk/find_dlg.h"
64 #include "gtk/goto_dlg.h"
65 #include "gtk/summary_dlg.h"
66 #include "gtk/prefs_dlg.h"
67 #include "gtk/packet_win.h"
68 #include "gtk/follow_tcp.h"
69 #include "gtk/follow_udp.h"
70 #include "gtk/follow_ssl.h"
71 #include "gtk/decode_as_dlg.h"
72 #include "gtk/help_dlg.h"
73 #include "gtk/supported_protos_dlg.h"
74 #include "gtk/proto_dlg.h"
75 #include "gtk/proto_hier_stats_dlg.h"
76 #include "gtk/keys.h"
77 #include "gtk/stock_icons.h"
78 #include "gtk/gtkglobals.h"
79 #include "gtk/recent.h"
80 #include "gtk/main_proto_draw.h"
81 #include "gtk/conversations_table.h"
82 #include "gtk/hostlist_table.h"
83 #include "gtk/packet_history.h"
84 #include "gtk/sctp_stat.h"
85 #include "gtk/firewall_dlg.h"
86 #include "gtk/u3.h"
87 #include "gtk/macros_dlg.h"
88 #include "gtk/export_object.h"
89 #include "gtk/gui_stat_menu.h"
90 #include "gtk/main.h"
91 #include "gtk/menus.h"
92 #include "gtk/main_toolbar.h"
93 #include "gtk/main_welcome.h"
94 #include "gtk/uat_gui.h"
95 #include "gtk/gui_utils.h"
96
97 #ifdef NEW_PACKET_LIST
98 #include "gtk/new_packet_list.h"
99 #else
100 #include "gtk/main_packet_list.h"
101 #endif
102
103 #ifdef HAVE_IGE_MAC_INTEGRATION
104 #include <ige-mac-menu.h>
105 #endif
106
107 typedef struct _menu_item {
108     char    *name;
109     gint    group;
110     const char *stock_id;
111     gboolean enabled;
112     GtkItemFactoryCallback callback;
113     gpointer callback_data;
114     gboolean (*selected_packet_enabled)(frame_data *, epan_dissect_t *, gpointer callback_data);
115     gboolean (*selected_tree_row_enabled)(field_info *, gpointer callback_data);
116     GList *children;
117 } menu_item_t;
118
119 static GList *tap_menu_tree_root = NULL;
120
121 GtkWidget *popup_menu_object;
122
123
124 #define GTK_MENU_FUNC(a) ((GtkItemFactoryCallback)(a))
125
126 static void merge_all_tap_menus(GList *node);
127 static void clear_menu_recent_capture_file_cmd_cb(GtkWidget *w, gpointer unused _U_);
128
129 static void menus_init(void);
130 static void set_menu_sensitivity (GtkItemFactory *, const gchar *, gint);
131 static void show_hide_cb(GtkWidget *w, gpointer data, gint action);
132 static void timestamp_format_cb(GtkWidget *w, gpointer d, gint action);
133 static void timestamp_precision_cb(GtkWidget *w, gpointer d, gint action);
134 static void name_resolution_cb(GtkWidget *w, gpointer d, gint action);
135 #ifdef HAVE_LIBPCAP
136 static void auto_scroll_live_cb(GtkWidget *w, gpointer d);
137 #endif
138 static void colorize_cb(GtkWidget *w, gpointer d);
139
140
141 /* This is the GtkItemFactoryEntry structure used to generate new menus.
142        Item 1: The menu path. The letter after the underscore indicates an
143                accelerator key once the menu is open.
144        Item 2: The accelerator key for the entry
145        Item 3: The callback function.
146        Item 4: The callback action.  This changes the parameters with
147                which the function is called.  The default is 0.
148        Item 5: The item type, used to define what kind of an item it is.
149                Here are the possible values:
150
151                NULL               -> "<Item>"
152                ""                 -> "<Item>"
153                "<Title>"          -> create a title item
154                "<Item>"           -> create a simple item
155                "<ImageItem>"      -> create an item holding an image (gtk2)
156                "<StockItem>"      -> create an item holding a stock image (gtk2)
157                "<CheckItem>"      -> create a check item
158                "<ToggleItem>"     -> create a toggle item
159                "<RadioItem>"      -> create a radio item
160                <path>             -> path of a radio item to link against
161                "<Separator>"      -> create a separator
162                "<Tearoff>"        -> create a tearoff separator (gtk2)
163                "<Branch>"         -> create an item to hold sub items (optional)
164                "<LastBranch>"     -> create a right justified branch
165        Item 6: extra data needed for ImageItem and StockItem (gtk2)
166     */
167
168 /*  As a general GUI guideline, we try to follow the Gnome Human Interface Guidelines, which can be found at:
169     http://developer.gnome.org/projects/gup/hig/1.0/index.html
170
171 Please note: there are some differences between the Gnome HIG menu suggestions and our implementation:
172
173 File/Open Recent:   the Gnome HIG suggests putting the list of recently used files as elements into the File menuitem.
174                     As this is ok for only a few items, this will become unhandy for 10 or even more list entries.
175                     For this reason, we use a submenu for this.
176
177 File/Close:         the Gnome HIG suggests putting this item just above the Quit item.
178                     This results in unintuitive behaviour as both Close and Quit items are very near together.
179                     By putting the Close item near the open item(s), it better suggests that it will close the
180                     currently opened/captured file only.
181 */
182
183 typedef enum {
184     SHOW_HIDE_MAIN_TOOLBAR = 1,
185     SHOW_HIDE_FILTER_TOOLBAR,
186     SHOW_HIDE_AIRPCAP_TOOLBAR,
187     SHOW_HIDE_STATUSBAR,
188     SHOW_HIDE_PACKET_LIST,
189     SHOW_HIDE_TREE_VIEW,
190     SHOW_HIDE_BYTE_VIEW
191 } show_hide_values_e;
192
193 typedef enum {
194     CONV_ETHER = 1,
195     CONV_IP,
196     CONV_TCP,
197     CONV_UDP,
198     CONV_CBA
199 } conv_values_e;
200
201 static char *
202 build_conversation_filter(int action, gboolean show_dialog)
203 {
204     packet_info *pi = &cfile.edt->pi;
205     char        *buf;
206
207
208     switch(action) {
209     case(CONV_CBA):
210         if (pi->profinet_type == 0) {
211             if (show_dialog) {
212                 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
213                     "Error filtering conversation.  Please make\n"
214                     "sure you have a PROFINET CBA packet selected.");
215             }
216             return NULL;
217         }
218
219         if( pi->net_src.type == AT_IPv4 && pi->net_dst.type == AT_IPv4
220         && pi->ipproto == IP_PROTO_TCP ) {
221             /* IPv4 */
222             switch(pi->profinet_type) {
223             case(1):
224                 buf = g_strdup_printf("(ip.src eq %s and ip.dst eq %s and cba.acco.dcom == 1) || (ip.src eq %s and ip.dst eq %s and cba.acco.dcom == 0)",
225                     ip_to_str( pi->net_dst.data),
226                     ip_to_str( pi->net_src.data),
227                     ip_to_str( pi->net_src.data),
228                     ip_to_str( pi->net_dst.data));
229                 break;
230             case(2):
231                 buf = g_strdup_printf("(ip.src eq %s and ip.dst eq %s and cba.acco.dcom == 1) || (ip.src eq %s and ip.dst eq %s and cba.acco.dcom == 0)",
232                     ip_to_str( pi->net_src.data),
233                     ip_to_str( pi->net_dst.data),
234                     ip_to_str( pi->net_dst.data),
235                     ip_to_str( pi->net_src.data));
236                 break;
237             case(3):
238                 buf = g_strdup_printf("(ip.src eq %s and ip.dst eq %s and cba.acco.srt == 1) || (ip.src eq %s and ip.dst eq %s and cba.acco.srt == 0)",
239                     ip_to_str( pi->net_dst.data),
240                     ip_to_str( pi->net_src.data),
241                     ip_to_str( pi->net_src.data),
242                     ip_to_str( pi->net_dst.data));
243                 break;
244             case(4):
245                 buf = g_strdup_printf("(ip.src eq %s and ip.dst eq %s and cba.acco.srt == 1) || (ip.src eq %s and ip.dst eq %s and cba.acco.srt == 0)",
246                     ip_to_str( pi->net_src.data),
247                     ip_to_str( pi->net_dst.data),
248                     ip_to_str( pi->net_dst.data),
249                     ip_to_str( pi->net_src.data));
250                 break;
251             default:
252                 return NULL;
253             }
254         } else {
255             return NULL;
256         }
257         break;
258     case(CONV_TCP):
259         if (pi->ipproto != IP_PROTO_TCP) {
260             if (show_dialog) {
261                 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
262                     "Error filtering conversation.  Please make\n"
263                     "sure you have a TCP packet selected.");
264             }
265             return NULL;
266         }
267
268         if( pi->net_src.type == AT_IPv4 && pi->net_dst.type == AT_IPv4 ) {
269             /* TCP over IPv4 */
270             buf = g_strdup_printf("(ip.addr eq %s and ip.addr eq %s) and (tcp.port eq %d and tcp.port eq %d)",
271                 ip_to_str( pi->net_src.data),
272                 ip_to_str( pi->net_dst.data),
273                 pi->srcport, pi->destport );
274         } else if( pi->net_src.type == AT_IPv6 && pi->net_dst.type == AT_IPv6 ) {
275             /* TCP over IPv6 */
276             buf = g_strdup_printf("(ipv6.addr eq %s and ipv6.addr eq %s) and (tcp.port eq %d and tcp.port eq %d)",
277                 ip6_to_str((const struct e_in6_addr *)pi->net_src.data),
278                 ip6_to_str((const struct e_in6_addr *)pi->net_dst.data),
279                 pi->srcport, pi->destport );
280         } else {
281             return NULL;
282         }
283         break;
284     case(CONV_UDP):
285         if (pi->ipproto != IP_PROTO_UDP) {
286             if (show_dialog) {
287                 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
288                     "Error filtering conversation.  Please make\n"
289                     "sure you have a UDP packet selected.");
290             }
291             return NULL;
292         }
293
294         if( pi->net_src.type == AT_IPv4 && pi->net_dst.type == AT_IPv4 ) {
295             /* UDP over IPv4 */
296             buf = g_strdup_printf("(ip.addr eq %s and ip.addr eq %s) and (udp.port eq %d and udp.port eq %d)",
297                 ip_to_str( pi->net_src.data),
298                 ip_to_str( pi->net_dst.data),
299                 pi->srcport, pi->destport );
300         } else if( pi->net_src.type == AT_IPv6 && pi->net_dst.type == AT_IPv6 ) {
301             /* UDP over IPv6 */
302             buf = g_strdup_printf("(ipv6.addr eq %s and ipv6.addr eq %s) and (udp.port eq %d and udp.port eq %d)",
303                 ip6_to_str((const struct e_in6_addr *)pi->net_src.data),
304                 ip6_to_str((const struct e_in6_addr *)pi->net_dst.data),
305                 pi->srcport, pi->destport );
306         } else {
307             return NULL;
308         }
309         break;
310     case(CONV_IP):
311         if ((pi->ethertype != ETHERTYPE_IP) && (pi->ethertype != ETHERTYPE_IPv6)) {
312             if (show_dialog) {
313                 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
314                     "Error filtering conversation.  Please make\n"
315                     "sure you have a IP packet selected.");
316             }
317             return NULL;
318         }
319
320         if( pi->net_src.type == AT_IPv4 && pi->net_dst.type == AT_IPv4 ) {
321             /* IPv4 */
322             buf = g_strdup_printf("ip.addr eq %s and ip.addr eq %s",
323                 ip_to_str( pi->net_src.data),
324                 ip_to_str( pi->net_dst.data));
325         } else if( pi->net_src.type == AT_IPv6 && pi->net_dst.type == AT_IPv6 ) {
326             /* IPv6 */
327             buf = g_strdup_printf("ipv6.addr eq %s and ipv6.addr eq %s",
328                 ip6_to_str((const struct e_in6_addr *)pi->net_src.data),
329                 ip6_to_str((const struct e_in6_addr *)pi->net_dst.data));
330         } else {
331             return NULL;
332         }
333         break;
334     case(CONV_ETHER):
335         /* XXX - is this the right way to check for Ethernet? */
336         /* check for the data link address type */
337         /* (ethertype will be 0 when used as length field) */
338         if (pi->dl_src.type != AT_ETHER) {
339             if (show_dialog) {
340                 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
341                     "Error filtering conversation.  Please make\n"
342                     "sure you have a Ethernet packet selected.");
343             }
344             return NULL;
345         }
346
347         if( pi->dl_src.type == AT_ETHER && pi->dl_dst.type == AT_ETHER ) {
348             /* Ethernet */
349             buf = g_strdup_printf("eth.addr eq %s and eth.addr eq %s",
350                 ether_to_str( pi->dl_src.data),
351                 ether_to_str( pi->dl_dst.data));
352         } else {
353             return NULL;
354         }
355         break;
356     default:
357         return NULL;
358     }
359
360     return buf;
361 }
362
363 void
364 conversation_cb(GtkWidget * w, gpointer data _U_, int action)
365 {
366     gchar       *filter;
367     GtkWidget   *filter_te;
368
369     if (cfile.current_frame) {
370         /* create a filter-string based on the selected packet and action */
371         filter = build_conversation_filter(action, TRUE);
372
373         /* Run the display filter so it goes in effect - even if it's the
374         same as the previous display filter. */
375         filter_te = g_object_get_data(G_OBJECT(w), E_DFILTER_TE_KEY);
376         gtk_entry_set_text(GTK_ENTRY(filter_te), filter);
377         main_filter_packets(&cfile, filter, TRUE);
378
379         g_free(filter);
380     }
381 }
382
383 void
384 colorize_conversation_cb(GtkWidget * w _U_, gpointer data _U_, int action)
385 {
386     gchar        *filter = NULL;
387
388     if( (action>>8) == 255 ) {
389         color_filters_reset_tmp();
390 #ifdef NEW_PACKET_LIST
391         new_packet_list_colorize_packets();
392 #else
393         cf_colorize_packets(&cfile);
394 #endif
395     } else if (cfile.current_frame) {
396         if( (action&0xff) == 0 ) {
397             /* colorize_conversation_cb was called from the window-menu
398              * or through an accelerator key. Try to build a conversation
399              * filter in the order TCP, UDP, IP, Ethernet and apply the
400              * coloring */
401             filter = build_conversation_filter(CONV_TCP,FALSE);
402             if( filter == NULL )
403                 filter = build_conversation_filter(CONV_UDP,FALSE);
404             if( filter == NULL )
405                 filter = build_conversation_filter(CONV_IP,FALSE);
406             if( filter == NULL )
407                 filter = build_conversation_filter(CONV_ETHER,FALSE);
408             if( filter == NULL ) {
409                 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Unable to build conversation filter.");
410                 return;
411             }
412         } else {
413             /* create a filter-string based on the selected packet and action */
414             filter = build_conversation_filter(action&0xff, TRUE);
415         }
416
417         if( (action>>8) == 0) {
418             /* Open the "new coloring filter" dialog with the filter */
419             color_display_with_filter(filter);
420         } else {
421             /* Set one of the temporary coloring filters */
422             color_filters_set_tmp((guint8)(action>>8),filter,FALSE);
423 #ifdef NEW_PACKET_LIST
424                         new_packet_list_colorize_packets();
425 #else
426                         cf_colorize_packets(&cfile);
427 #endif
428         }
429
430         g_free(filter);
431     }
432 }
433
434 /* main menu */
435 static GtkItemFactoryEntry menu_items[] =
436 {
437     {"/_File", NULL, NULL, 0, "<Branch>", NULL,},
438     {"/File/_Open...", "<control>O", GTK_MENU_FUNC(file_open_cmd_cb),
439                              0, "<StockItem>", GTK_STOCK_OPEN,},
440     {"/File/Open _Recent", NULL, NULL, 0, "<Branch>", NULL,},
441     {"/File/_Merge...", NULL, GTK_MENU_FUNC(file_merge_cmd_cb), 0, NULL, NULL,},
442     {"/File/_Close", "<control>W", GTK_MENU_FUNC(file_close_cmd_cb),
443                              0, "<StockItem>", GTK_STOCK_CLOSE,},
444     {"/File/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
445     {"/File/_Save", "<control>S", GTK_MENU_FUNC(file_save_cmd_cb),
446                              0, "<StockItem>", GTK_STOCK_SAVE,},
447     {"/File/Save _As...", "<shift><control>S", GTK_MENU_FUNC(file_save_as_cmd_cb),
448                              0, "<StockItem>", GTK_STOCK_SAVE_AS,},
449     {"/File/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
450     {"/File/File Set", NULL, NULL, 0, "<Branch>", NULL,},
451     {"/File/File Set/List Files", NULL, GTK_MENU_FUNC(fileset_cb), 0, "<StockItem>", WIRESHARK_STOCK_FILE_SET_LIST,},
452     {"/File/File Set/Next File", NULL, GTK_MENU_FUNC(fileset_next_cb), 0, "<StockItem>", WIRESHARK_STOCK_FILE_SET_NEXT,},
453     {"/File/File Set/Previous File", NULL, GTK_MENU_FUNC(fileset_previous_cb), 0, "<StockItem>", WIRESHARK_STOCK_FILE_SET_PREVIOUS,},
454     {"/File/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
455     {"/File/_Export", NULL, NULL, 0, "<Branch>", NULL,},
456 #if _WIN32
457     {"/File/Export/File...", NULL, GTK_MENU_FUNC(export_text_cmd_cb),
458                          0, NULL, NULL,},
459 #else
460     {"/File/Export/as \"Plain _Text\" file...", NULL, GTK_MENU_FUNC(export_text_cmd_cb),
461                              0, NULL, NULL,},
462     {"/File/Export/as \"_PostScript\" file...", NULL, GTK_MENU_FUNC(export_ps_cmd_cb),
463                              0, NULL, NULL,},
464     {"/File/Export/as \"_CSV\" (Comma Separated Values packet summary) file...",
465                              NULL, GTK_MENU_FUNC(export_csv_cmd_cb), 0, NULL, NULL,},
466     {"/File/Export/as \"C _Arrays\" (packet bytes) file...", NULL, GTK_MENU_FUNC(export_carrays_cmd_cb),
467                              0, NULL, NULL,},
468     {"/File/Export/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
469     {"/File/Export/as XML - \"P_SML\" (packet summary) file...", NULL, GTK_MENU_FUNC(export_psml_cmd_cb),
470                              0, NULL, NULL,},
471     {"/File/Export/as XML - \"P_DML\" (packet details) file...", NULL, GTK_MENU_FUNC(export_pdml_cmd_cb),
472                              0, NULL, NULL,},
473     {"/File/Export/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
474 #endif
475     {"/File/Export/Selected Packet _Bytes...", "<control>H", GTK_MENU_FUNC(savehex_cb),
476                              0, NULL, NULL,},
477     {"/File/Export/_Objects/_HTTP", NULL, GTK_MENU_FUNC(eo_http_cb), 0, NULL, NULL,},
478     {"/File/Export/_Objects/_DICOM", NULL, GTK_MENU_FUNC(eo_dicom_cb), 0, NULL, NULL,},
479
480     {"/File/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
481     {"/File/_Print...", "<control>P", GTK_MENU_FUNC(file_print_cmd_cb),
482                              0, "<StockItem>", GTK_STOCK_PRINT,},
483     {"/File/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
484     {"/File/_Quit", "<control>Q", GTK_MENU_FUNC(file_quit_cmd_cb),
485                              0, "<StockItem>", GTK_STOCK_QUIT,},
486     {"/_Edit", NULL, NULL, 0, "<Branch>", NULL,},
487     {"/Edit/Copy", NULL, NULL, 0, "<Branch>", NULL,},
488     {"/Edit/Copy/Description", "<shift><control>D", GTK_MENU_FUNC(copy_selected_plist_cb), COPY_SELECTED_DESCRIPTION, NULL, NULL,},
489     {"/Edit/Copy/Fieldname", "<shift><control>F", GTK_MENU_FUNC(copy_selected_plist_cb), COPY_SELECTED_FIELDNAME, NULL, NULL,},
490     {"/Edit/Copy/Value", "<shift><control>V", GTK_MENU_FUNC(copy_selected_plist_cb), COPY_SELECTED_VALUE, NULL, NULL,},
491     {"/Edit/Copy/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
492     {"/Edit/Copy/As Filter", "<shift><control>C", GTK_MENU_FUNC(match_selected_ptree_cb),
493                        MATCH_SELECTED_REPLACE|MATCH_SELECTED_COPY_ONLY, NULL, NULL,},
494 #if 0
495     /* Un-#if this when we actually implement Cut/Copy/Paste. */
496     {"/Edit/Cut", "<control>X", NULL,
497                              0, "<StockItem>", GTK_STOCK_CUT,},
498     {"/Edit/Copy", "<control>C", NULL,
499                              0, "<StockItem>", GTK_STOCK_COPY,},
500     {"/Edit/Paste", "<control>V", NULL,
501                              0, "<StockItem>", GTK_STOCK_PASTE,},
502 #endif
503     {"/Edit/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
504     {"/Edit/_Find Packet...", "<control>F",
505                              GTK_MENU_FUNC(find_frame_cb), 0, "<StockItem>", GTK_STOCK_FIND,},
506     {"/Edit/Find Ne_xt", "<control>N", GTK_MENU_FUNC(find_next_cb), 0, NULL, NULL,},
507     {"/Edit/Find Pre_vious", "<control>B", GTK_MENU_FUNC(find_previous_cb), 0, NULL, NULL,},
508     {"/Edit/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
509 #ifdef NEW_PACKET_LIST
510     {"/Edit/_Mark Packet (toggle)", "<control>M", GTK_MENU_FUNC(new_packet_list_mark_frame_cb),
511                        0, NULL, NULL,},
512 #else
513     {"/Edit/_Mark Packet (toggle)", "<control>M", GTK_MENU_FUNC(packet_list_mark_frame_cb),
514                        0, NULL, NULL,},
515 #endif /* NEW_PACKET_LIST */
516     {"/Edit/Find Next Mark", "<shift><control>N", GTK_MENU_FUNC(find_next_mark_cb),
517                        0, NULL, NULL,},
518     {"/Edit/Find Previous Mark", "<shift><control>B", GTK_MENU_FUNC(find_prev_mark_cb),
519                        0, NULL, NULL,},
520 #ifdef NEW_PACKET_LIST
521     {"/Edit/Mark _All Packets", "<control>A", GTK_MENU_FUNC(new_packet_list_mark_all_frames_cb), 0, NULL, NULL,},
522     {"/Edit/_Unmark All Packets", "<control>D", GTK_MENU_FUNC(new_packet_list_unmark_all_frames_cb), 0, NULL, NULL,},
523 #else
524     {"/Edit/Mark _All Packets", "<control>A", GTK_MENU_FUNC(packet_list_mark_all_frames_cb), 0, NULL, NULL,},
525     {"/Edit/_Unmark All Packets", "<control>D", GTK_MENU_FUNC(packet_list_unmark_all_frames_cb), 0, NULL, NULL,},
526 #endif /* NEW_PACKET_LIST */
527     {"/Edit/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
528     {"/Edit/Set Time Reference (toggle)", "<control>T", GTK_MENU_FUNC(reftime_frame_cb),
529                         REFTIME_TOGGLE, "<StockItem>", WIRESHARK_STOCK_TIME,},
530     {"/Edit/Find Next Reference", "<alt><shift><control>N", GTK_MENU_FUNC(reftime_frame_cb), REFTIME_FIND_NEXT, NULL, NULL,},
531     {"/Edit/Find Previous Reference", "<alt><shift><control>B", GTK_MENU_FUNC(reftime_frame_cb), REFTIME_FIND_PREV, NULL, NULL,},
532     {"/Edit/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
533     {"/Edit/_Configuration Profiles...", "<shift><control>A", GTK_MENU_FUNC(profile_dialog_cb), 0, NULL, NULL,},
534     {"/Edit/_Preferences...", "<shift><control>P", GTK_MENU_FUNC(prefs_page_cb),
535                              PREFS_PAGE_USER_INTERFACE, "<StockItem>", GTK_STOCK_PREFERENCES,},
536     {"/_View", NULL, NULL, 0, "<Branch>", NULL,},
537     {"/View/_Main Toolbar", NULL, GTK_MENU_FUNC(show_hide_cb), SHOW_HIDE_MAIN_TOOLBAR, "<CheckItem>", NULL,},
538     {"/View/_Filter Toolbar", NULL, GTK_MENU_FUNC(show_hide_cb), SHOW_HIDE_FILTER_TOOLBAR, "<CheckItem>", NULL,},
539 #ifdef HAVE_AIRPCAP
540     {"/View/_Wireless Toolbar", NULL, GTK_MENU_FUNC(show_hide_cb), SHOW_HIDE_AIRPCAP_TOOLBAR, "<CheckItem>", NULL,},
541 #endif
542     {"/View/_Statusbar", NULL, GTK_MENU_FUNC(show_hide_cb), SHOW_HIDE_STATUSBAR, "<CheckItem>", NULL,},
543     {"/View/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
544     {"/View/Packet _List", NULL, GTK_MENU_FUNC(show_hide_cb), SHOW_HIDE_PACKET_LIST, "<CheckItem>", NULL,},
545     {"/View/Packet _Details", NULL, GTK_MENU_FUNC(show_hide_cb), SHOW_HIDE_TREE_VIEW, "<CheckItem>", NULL,},
546     {"/View/Packet _Bytes", NULL, GTK_MENU_FUNC(show_hide_cb), SHOW_HIDE_BYTE_VIEW, "<CheckItem>", NULL,},
547     {"/View/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
548     {"/View/_Time Display Format", NULL, NULL, 0, "<Branch>", NULL,},
549     {"/View/Time Display Format/Date and Time of Day:   1970-01-01 01:02:03.123456", "<alt><control>1", GTK_MENU_FUNC(timestamp_format_cb),
550                         TS_ABSOLUTE_WITH_DATE, "<RadioItem>", NULL,},
551     {"/View/Time Display Format/Time of Day:   01:02:03.123456", "<alt><control>2", GTK_MENU_FUNC(timestamp_format_cb), 
552                         TS_ABSOLUTE, "/View/Time Display Format/Date and Time of Day:   1970-01-01 01:02:03.123456", NULL,},
553     {"/View/Time Display Format/Seconds Since Epoch (1970-01-01):   1234567890.123456", "<alt><control>3", GTK_MENU_FUNC(timestamp_format_cb),
554                         TS_EPOCH, "/View/Time Display Format/Date and Time of Day:   1970-01-01 01:02:03.123456", NULL,},
555     {"/View/Time Display Format/Seconds Since Beginning of Capture:   123.123456", "<alt><control>4", GTK_MENU_FUNC(timestamp_format_cb),
556                         TS_RELATIVE, "/View/Time Display Format/Date and Time of Day:   1970-01-01 01:02:03.123456", NULL,},
557     {"/View/Time Display Format/Seconds Since Previous Captured Packet:   1.123456", "<alt><control>5", GTK_MENU_FUNC(timestamp_format_cb),
558                         TS_DELTA, "/View/Time Display Format/Date and Time of Day:   1970-01-01 01:02:03.123456", NULL,},
559     {"/View/Time Display Format/Seconds Since Previous Displayed Packet:   1.123456", "<alt><control>6", GTK_MENU_FUNC(timestamp_format_cb),
560                         TS_DELTA_DIS, "/View/Time Display Format/Date and Time of Day:   1970-01-01 01:02:03.123456", NULL,},
561     {"/View/Time Display Format/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
562     {"/View/Time Display Format/Automatic (File Format Precision)", NULL, GTK_MENU_FUNC(timestamp_precision_cb),
563                         TS_PREC_AUTO, "<RadioItem>", NULL,},
564     {"/View/Time Display Format/Seconds:   0", NULL, GTK_MENU_FUNC(timestamp_precision_cb),
565                         TS_PREC_FIXED_SEC, "/View/Time Display Format/Automatic (File Format Precision)", NULL,},
566     {"/View/Time Display Format/Deciseconds:   0.1", NULL, GTK_MENU_FUNC(timestamp_precision_cb),
567                         TS_PREC_FIXED_DSEC, "/View/Time Display Format/Automatic (File Format Precision)", NULL,},
568     {"/View/Time Display Format/Centiseconds:   0.12", NULL, GTK_MENU_FUNC(timestamp_precision_cb),
569                         TS_PREC_FIXED_CSEC, "/View/Time Display Format/Automatic (File Format Precision)", NULL,},
570     {"/View/Time Display Format/Milliseconds:   0.123", NULL, GTK_MENU_FUNC(timestamp_precision_cb),
571                         TS_PREC_FIXED_MSEC, "/View/Time Display Format/Automatic (File Format Precision)", NULL,},
572     {"/View/Time Display Format/Microseconds:   0.123456", NULL, GTK_MENU_FUNC(timestamp_precision_cb),
573                         TS_PREC_FIXED_USEC, "/View/Time Display Format/Automatic (File Format Precision)", NULL,},
574     {"/View/Time Display Format/Nanoseconds:   0.123456789", NULL, GTK_MENU_FUNC(timestamp_precision_cb),
575                         TS_PREC_FIXED_NSEC, "/View/Time Display Format/Automatic (File Format Precision)", NULL,},
576     {"/View/Name Resol_ution", NULL, NULL, 0, "<Branch>", NULL,},
577     {"/View/Name Resolution/_Resolve Name", NULL, GTK_MENU_FUNC(resolve_name_cb), 0, NULL, NULL,},
578     {"/View/Name Resolution/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
579     {"/View/Name Resolution/Enable for _MAC Layer", NULL, GTK_MENU_FUNC(name_resolution_cb), RESOLV_MAC, "<CheckItem>", NULL,},
580     {"/View/Name Resolution/Enable for _Network Layer", NULL, GTK_MENU_FUNC(name_resolution_cb), RESOLV_NETWORK, "<CheckItem>", NULL,},
581     {"/View/Name Resolution/Enable for _Transport Layer", NULL, GTK_MENU_FUNC(name_resolution_cb), RESOLV_TRANSPORT, "<CheckItem>", NULL,},
582     {"/View/Colorize Packet List", NULL, colorize_cb, 0, "<CheckItem>", NULL,},
583 #ifdef HAVE_LIBPCAP
584     {"/View/Auto Scroll in Li_ve Capture", NULL, GTK_MENU_FUNC(auto_scroll_live_cb), 0, "<CheckItem>", NULL,},
585 #endif
586     {"/View/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
587     {"/View/_Zoom In", "<control>plus", GTK_MENU_FUNC(view_zoom_in_cb),
588                              0, "<StockItem>", GTK_STOCK_ZOOM_IN,},
589     {"/View/Zoom _Out", "<control>minus", GTK_MENU_FUNC(view_zoom_out_cb),
590                              0, "<StockItem>", GTK_STOCK_ZOOM_OUT,},
591     {"/View/_Normal Size", "<control>equal", GTK_MENU_FUNC(view_zoom_100_cb),
592                              0, "<StockItem>", GTK_STOCK_ZOOM_100,},
593 #ifdef NEW_PACKET_LIST
594     {"/View/Resize All Columns", "<shift><control>R", GTK_MENU_FUNC(new_packet_list_resize_columns_cb),
595                        0, "<StockItem>", WIRESHARK_STOCK_RESIZE_COLUMNS,},
596 #else
597     {"/View/Resize All Columns", "<shift><control>R", GTK_MENU_FUNC(packet_list_resize_columns_cb),
598                        0, "<StockItem>", WIRESHARK_STOCK_RESIZE_COLUMNS,},
599 #endif /* NEW_PACKET_LIST */
600     {"/View/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
601     {"/View/E_xpand Subtrees", "<shift>Right", GTK_MENU_FUNC(expand_tree_cb), 0, NULL, NULL,},
602     {"/View/_Expand All", "<control>Right", GTK_MENU_FUNC(expand_all_cb),
603                        0, NULL, NULL,},
604     {"/View/Collapse _All", "<control>Left", GTK_MENU_FUNC(collapse_all_cb),
605                        0, NULL, NULL,},
606     {"/View/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
607     {"/View/Colorize Conversation", NULL, NULL, 0, "<Branch>",NULL,},
608     {"/View/Colorize Conversation/Color 1", "<control>1",
609                        GTK_MENU_FUNC(colorize_conversation_cb), 1*256, "<StockItem>", WIRESHARK_STOCK_COLOR1,},
610     {"/View/Colorize Conversation/Color 2", "<control>2",
611                        GTK_MENU_FUNC(colorize_conversation_cb), 2*256, "<StockItem>", WIRESHARK_STOCK_COLOR2,},
612     {"/View/Colorize Conversation/Color 3", "<control>3",
613                        GTK_MENU_FUNC(colorize_conversation_cb), 3*256, "<StockItem>", WIRESHARK_STOCK_COLOR3,},
614     {"/View/Colorize Conversation/Color 4", "<control>4",
615                        GTK_MENU_FUNC(colorize_conversation_cb), 4*256, "<StockItem>", WIRESHARK_STOCK_COLOR4,},
616     {"/View/Colorize Conversation/Color 5", "<control>5",
617                        GTK_MENU_FUNC(colorize_conversation_cb), 5*256, "<StockItem>", WIRESHARK_STOCK_COLOR5,},
618     {"/View/Colorize Conversation/Color 6", "<control>6",
619                        GTK_MENU_FUNC(colorize_conversation_cb), 6*256, "<StockItem>", WIRESHARK_STOCK_COLOR6,},
620     {"/View/Colorize Conversation/Color 7", "<control>7",
621                        GTK_MENU_FUNC(colorize_conversation_cb), 7*256, "<StockItem>", WIRESHARK_STOCK_COLOR7,},
622     {"/View/Colorize Conversation/Color 8", "<control>8",
623                        GTK_MENU_FUNC(colorize_conversation_cb), 8*256, "<StockItem>", WIRESHARK_STOCK_COLOR8,},
624     {"/View/Colorize Conversation/Color 9", "<control>9",
625                        GTK_MENU_FUNC(colorize_conversation_cb), 9*256, "<StockItem>", WIRESHARK_STOCK_COLOR9,},
626     {"/View/Colorize Conversation/Color 10", "<control>0",
627                        GTK_MENU_FUNC(colorize_conversation_cb), 10*256, "<StockItem>", WIRESHARK_STOCK_COLOR0,},
628     {"/View/Colorize Conversation/<separator>", NULL,
629                        NULL, 0, "<Separator>",NULL,},
630     {"/View/Colorize Conversation/New Coloring Rule...", NULL,
631                        GTK_MENU_FUNC(colorize_conversation_cb), 0, "<StockItem>", GTK_STOCK_SELECT_COLOR,},
632     {"/View/Reset Coloring 1-10", "<control>space",
633                        GTK_MENU_FUNC(colorize_conversation_cb), 255*256, NULL, NULL,},
634     {"/View/_Coloring Rules...", NULL, color_display_cb,
635                        0, "<StockItem>", GTK_STOCK_SELECT_COLOR,},
636     {"/View/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
637
638
639     {"/View/Show Packet in New _Window", NULL,
640                        GTK_MENU_FUNC(new_window_cb), 0, NULL, NULL,},
641     {"/View/_Reload", "<control>R", GTK_MENU_FUNC(file_reload_cmd_cb),
642                              0, "<StockItem>", GTK_STOCK_REFRESH,},
643     {"/_Go", NULL, NULL, 0, "<Branch>", NULL,},
644     {"/Go/_Back", "<alt>Left",
645                              GTK_MENU_FUNC(history_back_cb), 0, "<StockItem>", GTK_STOCK_GO_BACK,},
646     {"/Go/_Forward", "<alt>Right",
647                              GTK_MENU_FUNC(history_forward_cb), 0, "<StockItem>", GTK_STOCK_GO_FORWARD,},
648     {"/Go/_Go to Packet...", "<control>G",
649                              GTK_MENU_FUNC(goto_frame_cb), 0, "<StockItem>", GTK_STOCK_JUMP_TO,},
650     {"/Go/Go to _Corresponding Packet", NULL, GTK_MENU_FUNC(goto_framenum_cb),
651                        0, NULL, NULL,},
652     {"/Go/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
653     {"/Go/Previous Packet", "<control>Up",
654                              GTK_MENU_FUNC(goto_previous_frame_cb), 0, "<StockItem>", GTK_STOCK_GO_UP,},
655     {"/Go/Next Packet", "<control>Down",
656                              GTK_MENU_FUNC(goto_next_frame_cb), 0, "<StockItem>", GTK_STOCK_GO_DOWN,},
657     {"/Go/F_irst Packet", "<control>Home",
658                              GTK_MENU_FUNC(goto_top_frame_cb), 0, "<StockItem>", GTK_STOCK_GOTO_TOP,},
659     {"/Go/_Last Packet", "<control>End",
660                              GTK_MENU_FUNC(goto_bottom_frame_cb), 0, "<StockItem>", GTK_STOCK_GOTO_BOTTOM,},
661 #ifdef HAVE_LIBPCAP
662     {"/_Capture", NULL, NULL, 0, "<Branch>", NULL,},
663     {"/Capture/_Interfaces...", "<control>I",
664                              GTK_MENU_FUNC(capture_if_cb), 0, "<StockItem>", WIRESHARK_STOCK_CAPTURE_INTERFACES,},
665     {"/Capture/_Options...", "<control>K",
666                              GTK_MENU_FUNC(capture_prep_cb), 0, "<StockItem>", WIRESHARK_STOCK_CAPTURE_OPTIONS,},
667     {"/Capture/_Start", "<control>E",
668                              GTK_MENU_FUNC(capture_start_cb), 0, "<StockItem>", WIRESHARK_STOCK_CAPTURE_START,},
669     {"/Capture/S_top", "<control>E", GTK_MENU_FUNC(capture_stop_cb),
670                              0, "<StockItem>", WIRESHARK_STOCK_CAPTURE_STOP,},
671     {"/Capture/_Restart", "<control>R", GTK_MENU_FUNC(capture_restart_cb),
672                              0, "<StockItem>", WIRESHARK_STOCK_CAPTURE_RESTART,},
673     {"/Capture/Capture _Filters...", NULL, GTK_MENU_FUNC(cfilter_dialog_cb),
674                        0, "<StockItem>", WIRESHARK_STOCK_CAPTURE_FILTER,},
675 #endif /* HAVE_LIBPCAP */
676     {"/_Analyze", NULL, NULL, 0, "<Branch>", NULL,},
677     {"/Analyze/_Display Filters...", NULL, GTK_MENU_FUNC(dfilter_dialog_cb),
678                        0, "<StockItem>", WIRESHARK_STOCK_DISPLAY_FILTER,},
679     {"/Analyze/Display Filter _Macros...", NULL, GTK_MENU_FUNC(macros_dialog_cb), 0, NULL, NULL,},
680     {"/Analyze/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
681     {"/Analyze/Apply as Column", NULL, GTK_MENU_FUNC(apply_as_custom_column_cb), 0, NULL, NULL},
682     {"/Analyze/Appl_y as Filter", NULL, NULL, 0, "<Branch>", NULL,},
683     {"/Analyze/Apply as Filter/_Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
684                        MATCH_SELECTED_REPLACE|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
685     {"/Analyze/Apply as Filter/_Not Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
686                        MATCH_SELECTED_NOT|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
687     {"/Analyze/Apply as Filter/... _and Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
688                        MATCH_SELECTED_AND|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
689     {"/Analyze/Apply as Filter/... _or Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
690                        MATCH_SELECTED_OR|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
691     {"/Analyze/Apply as Filter/... a_nd not Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
692                        MATCH_SELECTED_AND_NOT|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
693     {"/Analyze/Apply as Filter/... o_r not Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
694                        MATCH_SELECTED_OR_NOT|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
695     {"/Analyze/_Prepare a Filter", NULL, NULL, 0, "<Branch>", NULL,},
696     {"/Analyze/Prepare a Filter/_Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
697                        MATCH_SELECTED_REPLACE, NULL, NULL,},
698     {"/Analyze/Prepare a Filter/_Not Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
699                        MATCH_SELECTED_NOT, NULL, NULL,},
700     {"/Analyze/Prepare a Filter/... _and Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
701                        MATCH_SELECTED_AND, NULL, NULL,},
702     {"/Analyze/Prepare a Filter/... _or Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
703                        MATCH_SELECTED_OR, NULL, NULL,},
704     {"/Analyze/Prepare a Filter/... a_nd not Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
705                        MATCH_SELECTED_AND_NOT, NULL, NULL,},
706     {"/Analyze/Prepare a Filter/... o_r not Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
707                        MATCH_SELECTED_OR_NOT, NULL, NULL,},
708     {"/Analyze/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
709     {"/Analyze/_Enabled Protocols...", "<shift><control>E", GTK_MENU_FUNC(proto_cb), 
710                        0, "<StockItem>", WIRESHARK_STOCK_CHECKBOX,},
711     {"/Analyze/Decode _As...", NULL, GTK_MENU_FUNC(decode_as_cb),
712                        0, "<StockItem>", WIRESHARK_STOCK_DECODE_AS,},
713     {"/Analyze/_User Specified Decodes...", NULL,
714                        GTK_MENU_FUNC(decode_show_cb), 0, "<StockItem>", WIRESHARK_STOCK_DECODE_AS,},
715     {"/Analyze/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
716     {"/Analyze/_Follow TCP Stream", NULL,
717                        GTK_MENU_FUNC(follow_tcp_stream_cb), 0, NULL, NULL,},
718     {"/Analyze/_Follow UDP Stream", NULL,
719                        GTK_MENU_FUNC(follow_udp_stream_cb), 0, NULL, NULL,},
720     {"/Analyze/_Follow SSL Stream", NULL,
721                        GTK_MENU_FUNC(follow_ssl_stream_cb), 0, NULL, NULL,},
722     {"/_Statistics", NULL, NULL, 0, "<Branch>", NULL,},
723     {"/Statistics/_Summary", NULL, GTK_MENU_FUNC(summary_open_cb), 0, "<StockItem>", GTK_STOCK_PROPERTIES,},
724     {"/Statistics/_Protocol Hierarchy", NULL,
725                        GTK_MENU_FUNC(proto_hier_stats_cb), 0, NULL, NULL,},
726     {"/Statistics/Conversations", NULL,
727                        GTK_MENU_FUNC(init_conversation_notebook_cb), 0, "<StockItem>", WIRESHARK_STOCK_CONVERSATIONS,},
728     {"/Statistics/Endpoints", NULL,
729                        GTK_MENU_FUNC(init_hostlist_notebook_cb), 0, "<StockItem>", WIRESHARK_STOCK_ENDPOINTS,},
730     {"/Telephon_y", NULL, NULL, 0, "<Branch>", NULL,},
731     {"/_Tools", NULL, NULL, 0, "<Branch>", NULL,},
732     {"/Tools/Firewall ACL Rules", NULL,
733                        firewall_rule_cb, 0, NULL, NULL,},
734     {"/_Help", NULL, NULL, 0, "<Branch>", NULL,},
735     {"/Help/_Contents", "F1", GTK_MENU_FUNC(topic_menu_cb), HELP_CONTENT, "<StockItem>", GTK_STOCK_HELP,},
736     {"/Help/FAQ's", NULL, GTK_MENU_FUNC(topic_menu_cb), ONLINEPAGE_FAQ, NULL, NULL,},
737     {"/Help/Manual Pages", NULL, NULL, 0, "<Branch>", NULL,},
738     {"/Help/Manual Pages/Wireshark", NULL, GTK_MENU_FUNC(topic_menu_cb), LOCALPAGE_MAN_WIRESHARK, NULL, NULL,},
739     {"/Help/Manual Pages/Wireshark Filter", NULL, GTK_MENU_FUNC(topic_menu_cb), LOCALPAGE_MAN_WIRESHARK_FILTER, NULL, NULL,},
740     {"/Help/Manual Pages/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
741     {"/Help/Manual Pages/TShark", NULL, GTK_MENU_FUNC(topic_menu_cb), LOCALPAGE_MAN_TSHARK, NULL, NULL,},
742     {"/Help/Manual Pages/RawShark", NULL, GTK_MENU_FUNC(topic_menu_cb), LOCALPAGE_MAN_RAWSHARK, NULL, NULL,},
743     {"/Help/Manual Pages/Dumpcap", NULL, GTK_MENU_FUNC(topic_menu_cb), LOCALPAGE_MAN_DUMPCAP, NULL, NULL,},
744     {"/Help/Manual Pages/Mergecap", NULL, GTK_MENU_FUNC(topic_menu_cb), LOCALPAGE_MAN_MERGECAP, NULL, NULL,},
745     {"/Help/Manual Pages/Editcap", NULL, GTK_MENU_FUNC(topic_menu_cb), LOCALPAGE_MAN_EDITCAP, NULL, NULL,},
746     {"/Help/Manual Pages/Text2pcap", NULL, GTK_MENU_FUNC(topic_menu_cb), LOCALPAGE_MAN_TEXT2PCAP, NULL, NULL,},
747     {"/Help/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
748     {"/Help/Website", NULL, GTK_MENU_FUNC(topic_menu_cb), ONLINEPAGE_HOME, "<StockItem>", GTK_STOCK_HOME,},
749     {"/Help/Wiki", NULL, GTK_MENU_FUNC(topic_menu_cb), ONLINEPAGE_WIKI, "<StockItem>", WIRESHARK_STOCK_WIKI,},
750     {"/Help/Downloads", NULL, GTK_MENU_FUNC(topic_menu_cb), ONLINEPAGE_DOWNLOAD, NULL, NULL,},
751     {"/Help/Sample Captures", NULL, GTK_MENU_FUNC(topic_menu_cb), ONLINEPAGE_SAMPLE_FILES, NULL, NULL,},
752     {"/Help/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
753     {"/Help/_Supported Protocols (slow!)", NULL, GTK_MENU_FUNC(supported_cb), 0, NULL, NULL,},
754     {"/Help/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
755     {"/Help/_About Wireshark", NULL, GTK_MENU_FUNC(about_wireshark_cb),
756                        0, "<StockItem>", WIRESHARK_STOCK_ABOUT}
757 };
758
759
760 /* calculate the number of menu_items */
761 static int nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
762
763 /* packet list heading popup */
764 static GtkItemFactoryEntry packet_list_heading_items[] =
765 {
766 #ifdef NEW_PACKET_LIST
767     {"/Sort Ascending", NULL, GTK_MENU_FUNC(new_packet_list_column_menu_cb), COLUMN_SELECTED_SORT_ASCENDING, "<StockItem>", GTK_STOCK_SORT_ASCENDING,},
768     {"/Sort Descending", NULL, GTK_MENU_FUNC(new_packet_list_column_menu_cb), COLUMN_SELECTED_SORT_DESCENDING, "<StockItem>", GTK_STOCK_SORT_DESCENDING,},
769     {"/No Sorting", NULL, GTK_MENU_FUNC(new_packet_list_column_menu_cb), COLUMN_SELECTED_SORT_NONE, NULL, NULL,},
770
771     {"/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
772
773     {"/Align Left", NULL, GTK_MENU_FUNC(new_packet_list_column_menu_cb), COLUMN_SELECTED_ALIGN_LEFT, "<StockItem>", GTK_STOCK_JUSTIFY_LEFT,},
774     {"/Align Center", NULL, GTK_MENU_FUNC(new_packet_list_column_menu_cb), COLUMN_SELECTED_ALIGN_CENTER, "<StockItem>", GTK_STOCK_JUSTIFY_CENTER,},
775     {"/Align Right", NULL, GTK_MENU_FUNC(new_packet_list_column_menu_cb), COLUMN_SELECTED_ALIGN_RIGHT, "<StockItem>", GTK_STOCK_JUSTIFY_RIGHT,},
776
777     {"/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
778
779     {"/Column Preferences...", NULL, GTK_MENU_FUNC(prefs_page_cb), PREFS_PAGE_COLUMNS, "<StockItem>", GTK_STOCK_PREFERENCES,},
780     {"/Resize Column", NULL, GTK_MENU_FUNC(new_packet_list_column_menu_cb), COLUMN_SELECTED_RESIZE, "<StockItem>", WIRESHARK_STOCK_RESIZE_COLUMNS,},
781     {"/Rename Column Title...", NULL, GTK_MENU_FUNC(new_packet_list_column_menu_cb), COLUMN_SELECTED_RENAME, "<StockItem>", GTK_STOCK_BOLD,},
782
783     {"/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
784
785     {"/Remove Column", NULL, GTK_MENU_FUNC(new_packet_list_column_menu_cb), COLUMN_SELECTED_REMOVE, "<StockItem>", GTK_STOCK_DELETE,}
786 #else
787     {"/Sort Ascending", NULL, GTK_MENU_FUNC(packet_list_column_menu_cb), COLUMN_SELECTED_SORT_ASCENDING, "<StockItem>", GTK_STOCK_SORT_ASCENDING,},
788     {"/Sort Descending", NULL, GTK_MENU_FUNC(packet_list_column_menu_cb), COLUMN_SELECTED_SORT_DESCENDING, "<StockItem>", GTK_STOCK_SORT_DESCENDING,},
789     {"/No Sorting", NULL, GTK_MENU_FUNC(packet_list_column_menu_cb), COLUMN_SELECTED_SORT_NONE, NULL, NULL,},
790
791      {"/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
792
793      {"/Align Left", NULL, GTK_MENU_FUNC(packet_list_column_menu_cb), COLUMN_SELECTED_ALIGN_LEFT, "<StockItem>", GTK_STOCK_JUSTIFY_LEFT,},
794      {"/Align Center", NULL, GTK_MENU_FUNC(packet_list_column_menu_cb), COLUMN_SELECTED_ALIGN_CENTER, "<StockItem>", GTK_STOCK_JUSTIFY_CENTER,},
795      {"/Align Right", NULL, GTK_MENU_FUNC(packet_list_column_menu_cb), COLUMN_SELECTED_ALIGN_RIGHT, "<StockItem>", GTK_STOCK_JUSTIFY_RIGHT,},
796
797     {"/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
798
799     {"/Column Preferences...", NULL, GTK_MENU_FUNC(prefs_page_cb), PREFS_PAGE_COLUMNS, "<StockItem>", GTK_STOCK_PREFERENCES,},
800     {"/Resize Column", NULL, GTK_MENU_FUNC(packet_list_column_menu_cb), COLUMN_SELECTED_RESIZE, "<StockItem>", WIRESHARK_STOCK_RESIZE_COLUMNS,},
801     {"/Rename Column Title...", NULL, GTK_MENU_FUNC(packet_list_column_menu_cb), COLUMN_SELECTED_RENAME, "<StockItem>", GTK_STOCK_BOLD,},
802
803     {"/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
804
805     {"/Remove Column", NULL, GTK_MENU_FUNC(packet_list_column_menu_cb), COLUMN_SELECTED_REMOVE, "<StockItem>", GTK_STOCK_DELETE,}
806 #endif
807 };
808
809 /* packet list popup */
810 static GtkItemFactoryEntry packet_list_menu_items[] =
811 {
812 #ifdef NEW_PACKET_LIST
813     {"/Mark Packet (toggle)", NULL, GTK_MENU_FUNC(new_packet_list_mark_frame_cb), 0, NULL, NULL,},
814     {"/Ignore Packet (toggle)", NULL, GTK_MENU_FUNC(new_packet_list_ignore_frame_cb), 0, NULL, NULL,},
815 #else
816     {"/Mark Packet (toggle)", NULL, GTK_MENU_FUNC(packet_list_mark_frame_cb), 0, NULL, NULL,},
817     {"/Ignore Packet (toggle)", NULL, GTK_MENU_FUNC(packet_list_ignore_frame_cb), 0, NULL, NULL,},
818 #endif /* NEW_PACKET_LIST */
819     {"/Set Time Reference (toggle)", NULL, GTK_MENU_FUNC(reftime_frame_cb), REFTIME_TOGGLE, "<StockItem>", WIRESHARK_STOCK_TIME,},
820
821     {"/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
822
823     {"/Apply as Filter", NULL, NULL, 0, "<Branch>", NULL,},
824     {"/Apply as Filter/_Selected", NULL, GTK_MENU_FUNC(match_selected_plist_cb),
825                        MATCH_SELECTED_REPLACE|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
826     {"/Apply as Filter/_Not Selected", NULL, GTK_MENU_FUNC(match_selected_plist_cb),
827                        MATCH_SELECTED_NOT|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
828     {"/Apply as Filter/... _and Selected", NULL, GTK_MENU_FUNC(match_selected_plist_cb),
829                        MATCH_SELECTED_AND|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
830     {"/Apply as Filter/... _or Selected", NULL, GTK_MENU_FUNC(match_selected_plist_cb),
831                        MATCH_SELECTED_OR|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
832     {"/Apply as Filter/... a_nd not Selected", NULL, GTK_MENU_FUNC(match_selected_plist_cb),
833                        MATCH_SELECTED_AND_NOT|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
834     {"/Apply as Filter/... o_r not Selected", NULL, GTK_MENU_FUNC(match_selected_plist_cb),
835                        MATCH_SELECTED_OR_NOT|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
836     {"/Prepare a Filter", NULL, NULL, 0, "<Branch>", NULL,},
837     {"/Prepare a Filter/_Selected", NULL, GTK_MENU_FUNC(match_selected_plist_cb),
838                        MATCH_SELECTED_REPLACE, NULL, NULL,},
839     {"/Prepare a Filter/_Not Selected", NULL, GTK_MENU_FUNC(match_selected_plist_cb),
840                        MATCH_SELECTED_NOT, NULL, NULL,},
841     {"/Prepare a Filter/... _and Selected", NULL, GTK_MENU_FUNC(match_selected_plist_cb),
842                        MATCH_SELECTED_AND, NULL, NULL,},
843     {"/Prepare a Filter/... _or Selected", NULL, GTK_MENU_FUNC(match_selected_plist_cb),
844                        MATCH_SELECTED_OR, NULL, NULL,},
845     {"/Prepare a Filter/... a_nd not Selected", NULL, GTK_MENU_FUNC(match_selected_plist_cb),
846                        MATCH_SELECTED_AND_NOT, NULL, NULL,},
847     {"/Prepare a Filter/... o_r not Selected", NULL, GTK_MENU_FUNC(match_selected_plist_cb),
848                        MATCH_SELECTED_OR_NOT, NULL, NULL,},
849     {"/Conversation Filter", NULL, NULL, 0, "<Branch>",NULL,},
850     {"/Conversation Filter/Ethernet", NULL, GTK_MENU_FUNC(conversation_cb),
851                        CONV_ETHER, NULL, NULL,},
852     {"/Conversation Filter/IP", NULL, GTK_MENU_FUNC(conversation_cb),
853                        CONV_IP, NULL, NULL,},
854     {"/Conversation Filter/TCP", NULL, GTK_MENU_FUNC(conversation_cb),
855                        CONV_TCP, NULL, NULL,},
856     {"/Conversation Filter/UDP", NULL, GTK_MENU_FUNC(conversation_cb),
857                        CONV_UDP, NULL, NULL,},
858     {"/Conversation Filter/PN-CBA Server", NULL, GTK_MENU_FUNC(conversation_cb),
859                        CONV_CBA, NULL, NULL,},
860
861     {"/Colorize Conversation", NULL, NULL, 0, "<Branch>",NULL,},
862     {"/Colorize Conversation/Ethernet", NULL, NULL, 0, "<Branch>",NULL,},
863     {"/Colorize Conversation/Ethernet/Color 1", NULL,
864                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_ETHER+1*256, "<StockItem>", WIRESHARK_STOCK_COLOR1,},
865     {"/Colorize Conversation/Ethernet/Color 2", NULL,
866                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_ETHER+2*256, "<StockItem>", WIRESHARK_STOCK_COLOR2,},
867     {"/Colorize Conversation/Ethernet/Color 3", NULL,
868                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_ETHER+3*256, "<StockItem>", WIRESHARK_STOCK_COLOR3,},
869     {"/Colorize Conversation/Ethernet/Color 4", NULL,
870                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_ETHER+4*256, "<StockItem>", WIRESHARK_STOCK_COLOR4,},
871     {"/Colorize Conversation/Ethernet/Color 5", NULL,
872                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_ETHER+5*256, "<StockItem>", WIRESHARK_STOCK_COLOR5,},
873     {"/Colorize Conversation/Ethernet/Color 6", NULL,
874                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_ETHER+6*256, "<StockItem>", WIRESHARK_STOCK_COLOR6,},
875     {"/Colorize Conversation/Ethernet/Color 7", NULL,
876                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_ETHER+7*256, "<StockItem>", WIRESHARK_STOCK_COLOR7,},
877     {"/Colorize Conversation/Ethernet/Color 8", NULL,
878                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_ETHER+8*256, "<StockItem>", WIRESHARK_STOCK_COLOR8,},
879     {"/Colorize Conversation/Ethernet/Color 9", NULL,
880                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_ETHER+9*256, "<StockItem>", WIRESHARK_STOCK_COLOR9,},
881     {"/Colorize Conversation/Ethernet/Color 10", NULL,
882                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_ETHER+10*256, "<StockItem>", WIRESHARK_STOCK_COLOR0,},
883     {"/Colorize Conversation/Ethernet/<separator>", NULL,
884                        NULL, 0, "<Separator>",NULL,},
885     {"/Colorize Conversation/Ethernet/New Coloring Rule...", NULL,
886                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_ETHER, "<StockItem>", GTK_STOCK_SELECT_COLOR,},
887     {"/Colorize Conversation/IP", NULL, NULL, 0, "<Branch>",NULL,},
888     {"/Colorize Conversation/IP/Color 1", NULL,
889                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_IP+1*256, "<StockItem>", WIRESHARK_STOCK_COLOR1,},
890     {"/Colorize Conversation/IP/Color 2", NULL,
891                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_IP+2*256, "<StockItem>", WIRESHARK_STOCK_COLOR2,},
892     {"/Colorize Conversation/IP/Color 3", NULL,
893                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_IP+3*256, "<StockItem>", WIRESHARK_STOCK_COLOR3,},
894     {"/Colorize Conversation/IP/Color 4", NULL,
895                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_IP+4*256, "<StockItem>", WIRESHARK_STOCK_COLOR4,},
896     {"/Colorize Conversation/IP/Color 5", NULL,
897                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_IP+5*256, "<StockItem>", WIRESHARK_STOCK_COLOR5,},
898     {"/Colorize Conversation/IP/Color 6", NULL,
899                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_IP+6*256, "<StockItem>", WIRESHARK_STOCK_COLOR6,},
900     {"/Colorize Conversation/IP/Color 7", NULL,
901                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_IP+7*256, "<StockItem>", WIRESHARK_STOCK_COLOR7,},
902     {"/Colorize Conversation/IP/Color 8", NULL,
903                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_IP+8*256, "<StockItem>", WIRESHARK_STOCK_COLOR8,},
904     {"/Colorize Conversation/IP/Color 9", NULL,
905                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_IP+9*256, "<StockItem>", WIRESHARK_STOCK_COLOR9,},
906     {"/Colorize Conversation/IP/Color 10", NULL,
907                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_IP+10*256, "<StockItem>", WIRESHARK_STOCK_COLOR0,},
908     {"/Colorize Conversation/IP/<separator>", NULL,
909                        NULL, 0, "<Separator>",NULL,},
910     {"/Colorize Conversation/IP/New Coloring Rule...", NULL,
911                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_IP, "<StockItem>", GTK_STOCK_SELECT_COLOR,},
912     {"/Colorize Conversation/TCP", NULL, NULL, 0, "<Branch>",NULL,},
913     {"/Colorize Conversation/TCP/Color 1", NULL,
914                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_TCP+1*256, "<StockItem>", WIRESHARK_STOCK_COLOR1,},
915     {"/Colorize Conversation/TCP/Color 2", NULL,
916                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_TCP+2*256, "<StockItem>", WIRESHARK_STOCK_COLOR2,},
917     {"/Colorize Conversation/TCP/Color 3", NULL,
918                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_TCP+3*256, "<StockItem>", WIRESHARK_STOCK_COLOR3,},
919     {"/Colorize Conversation/TCP/Color 4", NULL,
920                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_TCP+4*256, "<StockItem>", WIRESHARK_STOCK_COLOR4,},
921     {"/Colorize Conversation/TCP/Color 5", NULL,
922                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_TCP+5*256, "<StockItem>", WIRESHARK_STOCK_COLOR5,},
923     {"/Colorize Conversation/TCP/Color 6", NULL,
924                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_TCP+6*256, "<StockItem>", WIRESHARK_STOCK_COLOR6,},
925     {"/Colorize Conversation/TCP/Color 7", NULL,
926                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_TCP+7*256, "<StockItem>", WIRESHARK_STOCK_COLOR7,},
927     {"/Colorize Conversation/TCP/Color 8", NULL,
928                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_TCP+8*256, "<StockItem>", WIRESHARK_STOCK_COLOR8,},
929     {"/Colorize Conversation/TCP/Color 9", NULL,
930                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_TCP+9*256, "<StockItem>", WIRESHARK_STOCK_COLOR9,},
931     {"/Colorize Conversation/TCP/Color 10", NULL,
932                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_TCP+10*256, "<StockItem>", WIRESHARK_STOCK_COLOR0,},
933     {"/Colorize Conversation/TCP/<separator>", NULL,
934                        NULL, 0, "<Separator>",NULL,},
935     {"/Colorize Conversation/TCP/New Coloring Rule...", NULL,
936                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_TCP, "<StockItem>", GTK_STOCK_SELECT_COLOR,},
937     {"/Colorize Conversation/UDP", NULL, NULL, 0, "<Branch>",NULL,},
938     {"/Colorize Conversation/UDP/Color 1", NULL,
939                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_UDP+1*256, "<StockItem>", WIRESHARK_STOCK_COLOR1,},
940     {"/Colorize Conversation/UDP/Color 2", NULL,
941                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_UDP+2*256, "<StockItem>", WIRESHARK_STOCK_COLOR2,},
942     {"/Colorize Conversation/UDP/Color 3", NULL,
943                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_UDP+3*256, "<StockItem>", WIRESHARK_STOCK_COLOR3,},
944     {"/Colorize Conversation/UDP/Color 4", NULL,
945                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_UDP+4*256, "<StockItem>", WIRESHARK_STOCK_COLOR4,},
946     {"/Colorize Conversation/UDP/Color 5", NULL,
947                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_UDP+5*256, "<StockItem>", WIRESHARK_STOCK_COLOR5,},
948     {"/Colorize Conversation/UDP/Color 6", NULL,
949                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_UDP+6*256, "<StockItem>", WIRESHARK_STOCK_COLOR6,},
950     {"/Colorize Conversation/UDP/Color 7", NULL,
951                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_UDP+7*256, "<StockItem>", WIRESHARK_STOCK_COLOR7,},
952     {"/Colorize Conversation/UDP/Color 8", NULL,
953                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_UDP+8*256, "<StockItem>", WIRESHARK_STOCK_COLOR8,},
954     {"/Colorize Conversation/UDP/Color 9", NULL,
955                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_UDP+9*256, "<StockItem>", WIRESHARK_STOCK_COLOR9,},
956     {"/Colorize Conversation/UDP/Color 10", NULL,
957                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_UDP+10*256, "<StockItem>", WIRESHARK_STOCK_COLOR0,},
958     {"/Colorize Conversation/UDP/<separator>", NULL,
959                        NULL, 0, "<Separator>",NULL,},
960     {"/Colorize Conversation/UDP/New Coloring Rule...", NULL,
961                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_UDP, "<StockItem>", GTK_STOCK_SELECT_COLOR,},
962     {"/Colorize Conversation/PN-CBA Server", NULL, NULL, 0, "<Branch>",NULL,},
963     {"/Colorize Conversation/PN-CBA Server/Color 1", NULL,
964                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_CBA+1*256, "<StockItem>", WIRESHARK_STOCK_COLOR1,},
965     {"/Colorize Conversation/PN-CBA Server/Color 2", NULL,
966                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_CBA+2*256, "<StockItem>", WIRESHARK_STOCK_COLOR2,},
967     {"/Colorize Conversation/PN-CBA Server/Color 3", NULL,
968                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_CBA+3*256, "<StockItem>", WIRESHARK_STOCK_COLOR3,},
969     {"/Colorize Conversation/PN-CBA Server/Color 4", NULL,
970                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_CBA+4*256, "<StockItem>", WIRESHARK_STOCK_COLOR4,},
971     {"/Colorize Conversation/PN-CBA Server/Color 5", NULL,
972                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_CBA+5*256, "<StockItem>", WIRESHARK_STOCK_COLOR5,},
973     {"/Colorize Conversation/PN-CBA Server/Color 6", NULL,
974                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_CBA+6*256, "<StockItem>", WIRESHARK_STOCK_COLOR6,},
975     {"/Colorize Conversation/PN-CBA Server/Color 7", NULL,
976                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_CBA+7*256, "<StockItem>", WIRESHARK_STOCK_COLOR7,},
977     {"/Colorize Conversation/PN-CBA Server/Color 8", NULL,
978                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_CBA+8*256, "<StockItem>", WIRESHARK_STOCK_COLOR8,},
979     {"/Colorize Conversation/PN-CBA Server/Color 9", NULL,
980                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_CBA+9*256, "<StockItem>", WIRESHARK_STOCK_COLOR9,},
981     {"/Colorize Conversation/PN-CBA Server/Color 10", NULL,
982                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_CBA+10*256, "<StockItem>", WIRESHARK_STOCK_COLOR0,},
983     {"/Colorize Conversation/PN-CBA Server/<separator>", NULL,
984                        NULL, 0, "<Separator>",NULL,},
985     {"/Colorize Conversation/PN-CBA Server/New Coloring Rule...", NULL,
986                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_CBA, "<StockItem>", GTK_STOCK_SELECT_COLOR,},
987
988     {"/SCTP", NULL, NULL, 0, "<Branch>",NULL,},
989     {"/SCTP/Analyse this Association", NULL, GTK_MENU_FUNC(sctp_analyse_start),
990                        0, NULL,NULL,},
991     {"/SCTP/Prepare Filter for this Association", NULL, (sctp_set_assoc_filter),
992                        0, NULL,NULL,},
993
994     {"/Follow TCP Stream", NULL, (follow_tcp_stream_cb),
995                        0, NULL, NULL,},
996     {"/Follow UDP Stream", NULL, (follow_udp_stream_cb),
997                        0, NULL, NULL,},
998     {"/Follow SSL Stream", NULL, (follow_ssl_stream_cb),
999                        0, NULL, NULL,},
1000
1001     {"/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
1002     {"/Copy", NULL, NULL, 0, "<Branch>", NULL,},
1003 #ifdef NEW_PACKET_LIST
1004     {"/Copy/Summary (Text)", NULL, GTK_MENU_FUNC(new_packet_list_copy_summary_cb), CS_TEXT, NULL, NULL,},
1005     {"/Copy/Summary (CSV)", NULL, GTK_MENU_FUNC(new_packet_list_copy_summary_cb), CS_CSV, NULL, NULL,},
1006     {"/Copy/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
1007 #else
1008     {"/Copy/Summary (Text)", NULL, GTK_MENU_FUNC(packet_list_copy_summary_cb), CS_TEXT, NULL, NULL,},
1009     {"/Copy/Summary (CSV)", NULL, GTK_MENU_FUNC(packet_list_copy_summary_cb), CS_CSV, NULL, NULL,},
1010     {"/Copy/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
1011 #endif /* NEW_PACKET_LIST */
1012     {"/Copy/As Filter", NULL, GTK_MENU_FUNC(match_selected_plist_cb),
1013                        MATCH_SELECTED_REPLACE|MATCH_SELECTED_COPY_ONLY, NULL, NULL,},
1014     {"/Copy/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
1015     {"/Copy/Bytes (Offset Hex Text)", NULL, GTK_MENU_FUNC(copy_hex_cb), CD_ALLINFO, NULL, NULL,},
1016     {"/Copy/Bytes (Offset Hex)", NULL, GTK_MENU_FUNC(copy_hex_cb), CD_HEXCOLUMNS, NULL, NULL,},
1017     {"/Copy/Bytes (Printable Text Only)", NULL, GTK_MENU_FUNC(copy_hex_cb), CD_TEXTONLY, NULL, NULL,},
1018     {"/Copy/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
1019     {"/Copy/Bytes (Hex Stream)", NULL, GTK_MENU_FUNC(copy_hex_cb), CD_HEX, NULL, NULL,},
1020     {"/Copy/Bytes (Binary Stream)", NULL, GTK_MENU_FUNC(copy_hex_cb), CD_BINARY, NULL, NULL,},
1021
1022     {"/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
1023
1024     {"/Decode As...", NULL, GTK_MENU_FUNC(decode_as_cb), 0, "<StockItem>", WIRESHARK_STOCK_DECODE_AS,},
1025     {"/Print...", NULL, GTK_MENU_FUNC(file_print_selected_cmd_cb), 0, "<StockItem>", GTK_STOCK_PRINT,},
1026     {"/Show Packet in New Window", NULL, GTK_MENU_FUNC(new_window_cb),
1027                        0, NULL, NULL}
1028 };
1029
1030 static GtkItemFactoryEntry tree_view_menu_items[] =
1031 {
1032
1033     {"/Expand Subtrees", NULL, GTK_MENU_FUNC(expand_tree_cb), 0, NULL, NULL,},
1034     {"/Expand All", NULL, GTK_MENU_FUNC(expand_all_cb), 0, NULL, NULL,},
1035     {"/Collapse All", NULL, GTK_MENU_FUNC(collapse_all_cb), 0, NULL, NULL,},
1036
1037     {"/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
1038
1039     {"/Apply as Column", NULL, GTK_MENU_FUNC(apply_as_custom_column_cb), 0, NULL, NULL},
1040
1041     {"/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
1042
1043     {"/Apply as Filter", NULL, NULL, 0, "<Branch>", NULL,},
1044     {"/Apply as Filter/_Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
1045                        MATCH_SELECTED_REPLACE|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
1046     {"/Apply as Filter/_Not Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
1047                        MATCH_SELECTED_NOT|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
1048     {"/Apply as Filter/... _and Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
1049                        MATCH_SELECTED_AND|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
1050     {"/Apply as Filter/... _or Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
1051                        MATCH_SELECTED_OR|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
1052     {"/Apply as Filter/... a_nd not Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
1053                        MATCH_SELECTED_AND_NOT|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
1054     {"/Apply as Filter/... o_r not Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
1055                        MATCH_SELECTED_OR_NOT|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
1056
1057     {"/Prepare a Filter", NULL, NULL, 0, "<Branch>", NULL,},
1058     {"/Prepare a Filter/_Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
1059                        MATCH_SELECTED_REPLACE, NULL, NULL,},
1060     {"/Prepare a Filter/_Not Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
1061                        MATCH_SELECTED_NOT, NULL, NULL,},
1062     {"/Prepare a Filter/... _and Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
1063                        MATCH_SELECTED_AND, NULL, NULL,},
1064     {"/Prepare a Filter/... _or Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
1065                        MATCH_SELECTED_OR, NULL, NULL,},
1066     {"/Prepare a Filter/... a_nd not Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
1067                        MATCH_SELECTED_AND_NOT, NULL, NULL,},
1068     {"/Prepare a Filter/... o_r not Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
1069                        MATCH_SELECTED_OR_NOT, NULL, NULL,},
1070
1071     {"/Colorize with Filter", NULL, NULL, 0, "<Branch>", NULL,},
1072     {"/Colorize with Filter/Color 1", NULL, GTK_MENU_FUNC(colorize_selected_ptree_cb), 1, "<StockItem>", WIRESHARK_STOCK_COLOR1,},
1073     {"/Colorize with Filter/Color 2", NULL, GTK_MENU_FUNC(colorize_selected_ptree_cb), 2, "<StockItem>", WIRESHARK_STOCK_COLOR2,},
1074     {"/Colorize with Filter/Color 3", NULL, GTK_MENU_FUNC(colorize_selected_ptree_cb), 3, "<StockItem>", WIRESHARK_STOCK_COLOR3,},
1075     {"/Colorize with Filter/Color 4", NULL, GTK_MENU_FUNC(colorize_selected_ptree_cb), 4, "<StockItem>", WIRESHARK_STOCK_COLOR4,},
1076     {"/Colorize with Filter/Color 5", NULL, GTK_MENU_FUNC(colorize_selected_ptree_cb), 5, "<StockItem>", WIRESHARK_STOCK_COLOR5,},
1077     {"/Colorize with Filter/Color 6", NULL, GTK_MENU_FUNC(colorize_selected_ptree_cb), 6, "<StockItem>", WIRESHARK_STOCK_COLOR6,},
1078     {"/Colorize with Filter/Color 7", NULL, GTK_MENU_FUNC(colorize_selected_ptree_cb), 7, "<StockItem>", WIRESHARK_STOCK_COLOR7,},
1079     {"/Colorize with Filter/Color 8", NULL, GTK_MENU_FUNC(colorize_selected_ptree_cb), 8, "<StockItem>", WIRESHARK_STOCK_COLOR8,},
1080     {"/Colorize with Filter/Color 9", NULL, GTK_MENU_FUNC(colorize_selected_ptree_cb), 9, "<StockItem>", WIRESHARK_STOCK_COLOR9,},
1081     {"/Colorize with Filter/Color 10", NULL, GTK_MENU_FUNC(colorize_selected_ptree_cb), 10, "<StockItem>", WIRESHARK_STOCK_COLOR0,},
1082     {"/Colorize with Filter/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
1083     {"/Colorize with Filter/New Coloring Rule...", NULL, GTK_MENU_FUNC(colorize_selected_ptree_cb), 0, "<StockItem>", GTK_STOCK_SELECT_COLOR,},
1084
1085     {"/Follow TCP Stream", NULL, GTK_MENU_FUNC(follow_tcp_stream_cb),
1086                        0, NULL, NULL,},
1087     {"/Follow UDP Stream", NULL, GTK_MENU_FUNC(follow_udp_stream_cb),
1088                        0, NULL, NULL,},
1089     {"/Follow SSL Stream", NULL, GTK_MENU_FUNC(follow_ssl_stream_cb),
1090                        0, NULL, NULL,},
1091
1092     {"/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
1093
1094     {"/Copy", NULL, NULL, 0, "<Branch>", NULL,},
1095     {"/Copy/Description", NULL, GTK_MENU_FUNC(copy_selected_plist_cb), COPY_SELECTED_DESCRIPTION, NULL, NULL,},
1096     {"/Copy/Fieldname", NULL, GTK_MENU_FUNC(copy_selected_plist_cb), COPY_SELECTED_FIELDNAME, NULL, NULL,},
1097     {"/Copy/Value", NULL, GTK_MENU_FUNC(copy_selected_plist_cb), COPY_SELECTED_VALUE, NULL, NULL,},
1098     {"/Copy/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
1099     {"/Copy/As Filter", NULL, GTK_MENU_FUNC(match_selected_ptree_cb), MATCH_SELECTED_REPLACE|MATCH_SELECTED_COPY_ONLY, NULL, NULL,},
1100     {"/Copy/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
1101     {"/Copy/Bytes (Offset Hex Text)", NULL, GTK_MENU_FUNC(copy_hex_cb), CD_ALLINFO | CD_FLAGS_SELECTEDONLY, NULL, NULL,},
1102     {"/Copy/Bytes (Offset Hex)", NULL, GTK_MENU_FUNC(copy_hex_cb), CD_HEXCOLUMNS | CD_FLAGS_SELECTEDONLY, NULL, NULL,},
1103     {"/Copy/Bytes (Printable Text Only)", NULL, GTK_MENU_FUNC(copy_hex_cb), CD_TEXTONLY | CD_FLAGS_SELECTEDONLY, NULL, NULL,},
1104     {"/Copy/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
1105     {"/Copy/Bytes (Hex Stream)", NULL, GTK_MENU_FUNC(copy_hex_cb), CD_HEX | CD_FLAGS_SELECTEDONLY, NULL, NULL,},
1106     {"/Copy/Bytes (Binary Stream)", NULL, GTK_MENU_FUNC(copy_hex_cb), CD_BINARY | CD_FLAGS_SELECTEDONLY, NULL, NULL,},
1107
1108     {"/Export Selected Packet Bytes...", NULL, GTK_MENU_FUNC(savehex_cb),
1109                        0, NULL, NULL,},
1110
1111     {"/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
1112
1113     {"/Wiki Protocol Page", NULL, GTK_MENU_FUNC(selected_ptree_info_cb),
1114                        0, "<StockItem>", WIRESHARK_STOCK_WIKI,},
1115     {"/Filter Field Reference", NULL, GTK_MENU_FUNC(selected_ptree_ref_cb),
1116                        0, "<StockItem>", WIRESHARK_STOCK_INTERNET,},
1117     {"/Protocol Preferences", NULL, NULL, 0, NULL, NULL,},
1118     {"/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
1119     {"/Decode As...", NULL, GTK_MENU_FUNC(decode_as_cb), 0, "<StockItem>", WIRESHARK_STOCK_DECODE_AS,},
1120     {"/Disable Protocol...", NULL, GTK_MENU_FUNC(proto_disable_cb), 0, "<StockItem>", WIRESHARK_STOCK_CHECKBOX,},
1121     {"/_Resolve Name", NULL, GTK_MENU_FUNC(resolve_name_cb), 0, NULL, NULL,},
1122     {"/_Go to Corresponding Packet", NULL, GTK_MENU_FUNC(goto_framenum_cb), 0, NULL, NULL,}
1123 };
1124
1125 static GtkItemFactoryEntry bytes_menu_items[] =
1126 {
1127     {"/Hex View", NULL, GTK_MENU_FUNC(select_bytes_view), BYTES_HEX, "<RadioItem>", NULL,},
1128     {"/Bits View", NULL, GTK_MENU_FUNC(select_bytes_view), BYTES_BITS, "/Hex View", NULL,}
1129 };
1130
1131
1132 static int initialize = TRUE;
1133 static GtkItemFactory *main_menu_factory = NULL;
1134 static GtkItemFactory *packet_list_heading_factory = NULL;
1135 static GtkItemFactory *packet_list_menu_factory = NULL;
1136 static GtkItemFactory *tree_view_menu_factory = NULL;
1137 static GtkItemFactory *bytes_menu_factory = NULL;
1138
1139 static GSList *popup_menu_list = NULL;
1140
1141 static GtkAccelGroup *grp;
1142
1143 GtkWidget *
1144 main_menu_new(GtkAccelGroup ** table) {
1145     GtkWidget *menubar;
1146 #ifdef HAVE_IGE_MAC_INTEGRATION
1147     GtkWidget *quit_item, *about_item, *preferences_item;
1148     IgeMacMenuGroup *group;
1149 #endif
1150
1151     grp = gtk_accel_group_new();
1152
1153     if (initialize)
1154         menus_init();
1155
1156     menubar = main_menu_factory->widget;
1157
1158 #ifdef HAVE_IGE_MAC_INTEGRATION
1159     if(prefs.gui_macosx_style) {
1160         ige_mac_menu_set_menu_bar(GTK_MENU_SHELL(menubar));
1161         ige_mac_menu_set_global_key_handler_enabled(TRUE);
1162
1163         /* Create menu items to populate the application menu with.  We have to
1164          * do this because we are still using the old GtkItemFactory API for
1165          * the main menu. */
1166         group = ige_mac_menu_add_app_menu_group();
1167         about_item = gtk_menu_item_new_with_label("About");
1168         g_signal_connect(about_item, "activate", G_CALLBACK(about_wireshark_cb),
1169                          NULL);
1170         ige_mac_menu_add_app_menu_item(group, GTK_MENU_ITEM(about_item), NULL);
1171
1172         group = ige_mac_menu_add_app_menu_group();
1173         preferences_item = gtk_menu_item_new_with_label("Preferences");
1174         g_signal_connect(preferences_item, "activate", G_CALLBACK(prefs_cb),
1175                          NULL);
1176         ige_mac_menu_add_app_menu_item(group, GTK_MENU_ITEM(preferences_item),
1177                                        NULL);
1178     }
1179
1180     /* The quit item in the application menu shows up whenever ige mac
1181      * integration is enabled, even if the OS X UI style in Wireshark isn't
1182      * turned on. */
1183     quit_item = gtk_menu_item_new_with_label("Quit");
1184     g_signal_connect(quit_item, "activate", G_CALLBACK(file_quit_cmd_cb), NULL);
1185     ige_mac_menu_set_quit_menu_item(GTK_MENU_ITEM(quit_item));
1186 #endif
1187
1188     if (table)
1189         *table = grp;
1190
1191     return menubar;
1192 }
1193
1194
1195 void menu_dissector_filter_cb(  GtkWidget *widget _U_,
1196                                 gpointer callback_data,
1197                                 guint callback_action _U_)
1198 {
1199     dissector_filter_t      *filter_entry = callback_data;
1200     GtkWidget               *filter_te;
1201     const char              *buf;    
1202
1203
1204     filter_te = g_object_get_data(G_OBJECT(popup_menu_object), E_DFILTER_TE_KEY);
1205
1206     /* XXX - this gets the packet_info of the last dissected packet, */
1207     /* which is not necessarily the last selected packet */
1208     /* e.g. "Update list of packets in real time" won't work correct */
1209     buf = filter_entry->build_filter_string(&cfile.edt->pi);
1210
1211     gtk_entry_set_text(GTK_ENTRY(filter_te), buf);
1212
1213     /* Run the display filter so it goes in effect - even if it's the
1214        same as the previous display filter. */
1215     main_filter_packets(&cfile, buf, TRUE);
1216
1217     g_free( (void *) buf);
1218 }
1219
1220 gboolean menu_dissector_filter_spe_cb(frame_data *fd _U_, epan_dissect_t *edt, gpointer callback_data) {
1221     dissector_filter_t *filter_entry = callback_data;
1222
1223     /* XXX - this gets the packet_info of the last dissected packet, */
1224     /* which is not necessarily the last selected packet */
1225     /* e.g. "Update list of packets in real time" won't work correct */
1226     return (edt != NULL) ? filter_entry->is_filter_valid(&edt->pi) : FALSE;
1227 }
1228
1229 void menu_dissector_filter(void) {
1230     GList *list_entry = dissector_filter_list;
1231     dissector_filter_t *filter_entry;
1232
1233     while(list_entry != NULL) {
1234         filter_entry = list_entry->data;
1235
1236         register_stat_menu_item(filter_entry->name, REGISTER_ANALYZE_GROUP_CONVERSATION_FILTER,
1237             menu_dissector_filter_cb,
1238             menu_dissector_filter_spe_cb,
1239             NULL /* selected_tree_row_enabled */,
1240             filter_entry);
1241
1242         list_entry = g_list_next(list_entry);
1243     }
1244 }
1245
1246
1247 static void
1248 menus_init(void) {
1249     if (initialize) {
1250         initialize = FALSE;
1251
1252     popup_menu_object = gtk_menu_new();
1253
1254     /* packet list heading pop-up menu */
1255     packet_list_heading_factory = gtk_item_factory_new(GTK_TYPE_MENU, "<main>", NULL);
1256     gtk_item_factory_create_items_ac(packet_list_heading_factory, sizeof(packet_list_heading_items)/sizeof(packet_list_heading_items[0]), packet_list_heading_items, popup_menu_object, 2);
1257     g_object_set_data(G_OBJECT(popup_menu_object), PM_PACKET_LIST_COL_KEY,
1258                     packet_list_heading_factory->widget);
1259     popup_menu_list = g_slist_append((GSList *)popup_menu_list, packet_list_heading_factory);
1260
1261     /* packet list pop-up menu */
1262     packet_list_menu_factory = gtk_item_factory_new(GTK_TYPE_MENU, "<main>", NULL);
1263     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);
1264     g_object_set_data(G_OBJECT(popup_menu_object), PM_PACKET_LIST_KEY,
1265                     packet_list_menu_factory->widget);
1266     popup_menu_list = g_slist_append((GSList *)popup_menu_list, packet_list_menu_factory);
1267
1268     /* packet detail pop-up menu */
1269     tree_view_menu_factory = gtk_item_factory_new(GTK_TYPE_MENU, "<main>", NULL);
1270     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);
1271     g_object_set_data(G_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY,
1272                     tree_view_menu_factory->widget);
1273     popup_menu_list = g_slist_append((GSList *)popup_menu_list, tree_view_menu_factory);
1274
1275     /*
1276      * Hex dump pop-up menu.
1277      * We provide our own empty menu to suppress the default pop-up menu
1278      * for text widgets.
1279      */
1280     bytes_menu_factory = gtk_item_factory_new(GTK_TYPE_MENU, "<main>", NULL);
1281     gtk_item_factory_create_items_ac(bytes_menu_factory, sizeof(bytes_menu_items)/sizeof(bytes_menu_items[0]), bytes_menu_items, popup_menu_object, 2);
1282     g_object_set_data(G_OBJECT(popup_menu_object), PM_BYTES_VIEW_KEY,
1283                     bytes_menu_factory->widget);
1284     popup_menu_list = g_slist_append((GSList *)popup_menu_list, bytes_menu_factory);
1285
1286     /* main */
1287     main_menu_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", grp);
1288     gtk_item_factory_create_items_ac(main_menu_factory, nmenu_items, menu_items, NULL, 2);
1289
1290     menu_dissector_filter();
1291     merge_all_tap_menus(tap_menu_tree_root);
1292
1293     /* Initialize enabled/disabled state of menu items */
1294     set_menus_for_capture_file(NULL);
1295 #if 0
1296     /* Un-#if this when we actually implement Cut/Copy/Paste.
1297        Then make sure you enable them when they can be done. */
1298     set_menu_sensitivity(main_menu_factory, "/Edit/Cut", FALSE);
1299     set_menu_sensitivity(main_menu_factory, "/Edit/Copy", FALSE);
1300     set_menu_sensitivity(main_menu_factory, "/Edit/Paste", FALSE);
1301 #endif
1302
1303     set_menus_for_captured_packets(FALSE);
1304     set_menus_for_selected_packet(&cfile);
1305     set_menus_for_selected_tree_row(&cfile);
1306     set_menus_for_capture_in_progress(FALSE);
1307     set_menus_for_file_set(/* dialog */TRUE, /* previous file */ FALSE, /* next_file */ FALSE);
1308
1309     /* init with an empty recent files list */
1310     clear_menu_recent_capture_file_cmd_cb(NULL, NULL);
1311
1312     }
1313 }
1314
1315
1316 static gint tap_menu_item_add_compare(gconstpointer a, gconstpointer b)
1317 {
1318     return strcmp(
1319         ((const menu_item_t *) a)->name,
1320         ((const menu_item_t *) b)->name);
1321 }
1322
1323
1324 /* add a menuitem below the current node */
1325 static GList * tap_menu_item_add(
1326     char *name,
1327     gint group,
1328     const char *stock_id,
1329     GtkItemFactoryCallback callback,
1330     gboolean (*selected_packet_enabled)(frame_data *, epan_dissect_t *, gpointer callback_data),
1331     gboolean (*selected_tree_row_enabled)(field_info *, gpointer callback_data),
1332     gpointer callback_data,
1333     GList *curnode)
1334 {
1335     menu_item_t *curr;
1336     menu_item_t *child;
1337
1338
1339     child = g_malloc(sizeof (menu_item_t));
1340     child->name             = name;
1341     child->group            = group;
1342     child->stock_id         = stock_id;
1343     child->callback         = callback;
1344     child->selected_packet_enabled = selected_packet_enabled;
1345     child->selected_tree_row_enabled = selected_tree_row_enabled;
1346     child->callback_data    = callback_data;
1347     child->enabled          = FALSE;
1348     child->children         = NULL;
1349
1350     /* insert the new child node into the parent */
1351     curr = curnode->data;
1352     curr->children = g_list_insert_sorted(curr->children, child, tap_menu_item_add_compare);
1353
1354     /* return the new node */
1355     /* XXX: improve this */
1356     return g_list_find(curr->children, child);
1357 }
1358
1359 /*
1360  * Add a new menu item for a tap.
1361  * This must be called after we've created the main menu, so it can't
1362  * be called from the routine that registers taps - we have to introduce
1363  * another per-tap registration routine.
1364  *
1365  * "callback" gets called when the menu item is selected; it should do
1366  * the work of creating the tap window.
1367  *
1368  * "selected_packet_enabled" gets called by "set_menus_for_selected_packet()";
1369  * it's passed a Boolean that's TRUE if a packet is selected and FALSE
1370  * otherwise, and should return TRUE if the tap will work now (which
1371  * might depend on whether a packet is selected and, if one is, on the
1372  * packet) and FALSE if not.
1373  *
1374  * "selected_tree_row_enabled" gets called by
1375  * "set_menus_for_selected_tree_row()"; it's passed a Boolean that's TRUE if
1376  * a protocol tree row is selected and FALSE otherwise, and should return
1377  * TRUE if the tap will work now (which might depend on whether a tree row
1378  * is selected and, if one is, on the tree row) and FALSE if not.
1379  */
1380 void
1381 register_stat_menu_item_stock(
1382     const char *name,
1383     register_stat_group_t group,
1384     const char *stock_id,
1385     GtkItemFactoryCallback callback,
1386     gboolean (*selected_packet_enabled)(frame_data *, epan_dissect_t *, gpointer callback_data),
1387     gboolean (*selected_tree_row_enabled)(field_info *, gpointer callback_data),
1388     gpointer callback_data)
1389 {
1390     /*static const char toolspath[] = "/Statistics/";*/
1391     const char *toolspath;
1392     const char *p;
1393     char *menupath;
1394     size_t menupathlen;
1395     menu_item_t *child;
1396     GList *curnode;
1397     GList *childnode;
1398
1399     /*
1400      * The menu path must be relative.
1401      */
1402     g_assert(*name != '/');
1403
1404     switch(group) {
1405     case(REGISTER_STAT_GROUP_GENERIC): toolspath = "/Statistics/"; break;
1406     case(REGISTER_STAT_GROUP_CONVERSATION_LIST): toolspath = "/Statistics/_Conversation List/"; break;
1407     case(REGISTER_STAT_GROUP_ENDPOINT_LIST): toolspath = "/Statistics/_Endpoint List/"; break;
1408     case(REGISTER_STAT_GROUP_RESPONSE_TIME): toolspath = "/Statistics/Service _Response Time/"; break;
1409     case(REGISTER_STAT_GROUP_UNSORTED): toolspath = "/Statistics/"; break;
1410     case(REGISTER_ANALYZE_GROUP_UNSORTED): toolspath = "/Analyze/"; break;
1411     case(REGISTER_ANALYZE_GROUP_CONVERSATION_FILTER): toolspath = "/Analyze/Conversation Filter/"; break;
1412     case(REGISTER_STAT_GROUP_TELEPHONY): toolspath = "/Telephony/"; break;
1413     case(REGISTER_TOOLS_GROUP_UNSORTED): toolspath = "/Tools/"; break;
1414     default:
1415         g_assert(!"no such menu group");
1416         toolspath = NULL;
1417     }
1418
1419     /* add the (empty) root node, if not already done */
1420     if(tap_menu_tree_root == NULL) {
1421         child = g_malloc0(sizeof (menu_item_t));
1422         tap_menu_tree_root = g_list_append(NULL, child);
1423     }
1424
1425     /*
1426      * Create any submenus required.
1427      */
1428     curnode = tap_menu_tree_root;
1429     p = name;
1430     while ((p = strchr(p, '/')) != NULL) {
1431         /*
1432          * OK, everything between "name" and "p" is
1433          * a menu relative subtree into which the menu item
1434          * will be placed.
1435          *
1436          * Construct the absolute path name of that subtree.
1437          */
1438         menupathlen = strlen(toolspath) + 1 + (p - name);
1439         menupath = g_malloc(menupathlen);
1440         g_strlcpy(menupath, toolspath, menupathlen);
1441         g_strlcat(menupath, name, menupathlen);
1442
1443         /*
1444          * Does there exist an entry with that path at this
1445          * level of the Analyze menu tree?
1446          */
1447         child = curnode->data;
1448         for (childnode = child->children; childnode != NULL; childnode = childnode->next) {
1449             child = childnode->data;
1450             if (strcmp(child->name, menupath) == 0)
1451                 break;
1452         }
1453         if (childnode == NULL) {
1454             /*
1455              * No.  Create such an item as a subtree, and
1456              * add it to the Tools menu tree.
1457              */
1458             childnode = tap_menu_item_add(
1459                 menupath, group, "", NULL, NULL ,NULL, NULL, curnode);
1460         } else {
1461             /*
1462              * Yes.  We don't need this "menupath" any longer.
1463              */
1464             g_free(menupath);
1465         }
1466         curnode = childnode;
1467
1468         /*
1469          * Skip over the '/' we found.
1470          */
1471         p++;
1472     }
1473
1474     /*
1475      * Construct the main menu path for the menu item.
1476      */
1477     menupathlen = strlen(toolspath) + 1 + strlen(name);
1478     menupath = g_malloc(menupathlen);
1479     g_strlcpy(menupath, toolspath, menupathlen);
1480     g_strlcat(menupath, name, menupathlen);
1481
1482     /*
1483      * Construct an item factory entry for the item, and add it to
1484      * the main menu.
1485      */
1486     tap_menu_item_add(
1487         menupath, group, stock_id, callback,
1488         selected_packet_enabled, selected_tree_row_enabled,
1489         callback_data, curnode);
1490 }
1491
1492
1493 void
1494 register_stat_menu_item(
1495     const char *name,
1496     register_stat_group_t group,
1497     GtkItemFactoryCallback callback,
1498     gboolean (*selected_packet_enabled)(frame_data *, epan_dissect_t *, gpointer callback_data),
1499     gboolean (*selected_tree_row_enabled)(field_info *, gpointer callback_data),
1500     gpointer callback_data)
1501 {
1502     register_stat_menu_item_stock(
1503         name,
1504         group,
1505         NULL,
1506         callback,
1507         selected_packet_enabled,
1508         selected_tree_row_enabled,
1509         callback_data);
1510 }
1511
1512 static guint merge_tap_menus_layered(GList *node, gint group) {
1513     GtkItemFactoryEntry *entry;
1514     GList       *child;
1515     guint       added = 0;
1516     menu_item_t *node_data = node->data;
1517
1518     /*
1519      * Is this a leaf node or an interior node?
1520      */
1521     if (node_data->children == NULL) {
1522         /*
1523          * It's a leaf node.
1524          */
1525
1526         /*
1527          * The root node doesn't correspond to a menu tree item; it
1528          * has a null name pointer.
1529          */
1530         if (node_data->name != NULL && group == node_data->group) {
1531             entry = g_malloc0(sizeof (GtkItemFactoryEntry));
1532             entry->path = node_data->name;
1533             entry->callback = node_data->callback;
1534             switch(group) {
1535             case(REGISTER_STAT_GROUP_UNSORTED):
1536                 break;
1537             case(REGISTER_STAT_GROUP_GENERIC):
1538                 break;
1539             case(REGISTER_STAT_GROUP_CONVERSATION_LIST):
1540                 entry->item_type = "<StockItem>";
1541                 entry->extra_data = WIRESHARK_STOCK_CONVERSATIONS;
1542                 break;
1543             case(REGISTER_STAT_GROUP_ENDPOINT_LIST):
1544                 entry->item_type = "<StockItem>";
1545                 entry->extra_data = WIRESHARK_STOCK_ENDPOINTS;
1546                 break;
1547             case(REGISTER_STAT_GROUP_RESPONSE_TIME):
1548                 entry->item_type = "<StockItem>";
1549                 entry->extra_data = WIRESHARK_STOCK_TIME;
1550                 break;
1551             case(REGISTER_STAT_GROUP_TELEPHONY):
1552                 break;
1553             case(REGISTER_ANALYZE_GROUP_UNSORTED):
1554                 break;
1555             case(REGISTER_ANALYZE_GROUP_CONVERSATION_FILTER):
1556                 break;
1557             case(REGISTER_TOOLS_GROUP_UNSORTED):
1558                 break;
1559             default:
1560                 g_assert_not_reached();
1561             }
1562             if(node_data->stock_id!= NULL) {
1563                 entry->item_type = "<StockItem>";
1564                 entry->extra_data = node_data->stock_id;
1565             }
1566             gtk_item_factory_create_item(main_menu_factory, entry, node_data->callback_data, /* callback_type */ 2);
1567             set_menu_sensitivity(main_menu_factory, node_data->name, FALSE); /* no capture file yet */
1568             added++;
1569             g_free(entry);
1570         }
1571     } else {
1572         /*
1573          * It's an interior node; call
1574          * "merge_tap_menus_layered()" on all its children
1575          */
1576
1577         /*
1578          * The root node doesn't correspond to a menu tree item; it
1579          * has a null name pointer.
1580          */
1581         if (node_data->name != NULL && group == node_data->group) {
1582             entry = g_malloc0(sizeof (GtkItemFactoryEntry));
1583             entry->path = node_data->name;
1584             entry->item_type = "<Branch>";
1585             gtk_item_factory_create_item(main_menu_factory, entry,
1586                 NULL, 2);
1587             set_menu_sensitivity(main_menu_factory, node_data->name,
1588                 FALSE);    /* no children yet */
1589             added++;
1590             g_free(entry);
1591         }
1592
1593         for (child = node_data->children; child != NULL; child =
1594             child->next) {
1595             added += merge_tap_menus_layered(child, group);
1596         }
1597     }
1598
1599     return added;
1600 }
1601
1602
1603 void merge_all_tap_menus(GList *node) {
1604     GtkItemFactoryEntry *sep_entry;
1605
1606     sep_entry = g_malloc0(sizeof (GtkItemFactoryEntry));
1607     sep_entry->item_type = "<Separator>";
1608     sep_entry->path = "/Statistics/";
1609
1610     /*
1611      * merge only the menu items of the specific group,
1612      * and then append a seperator
1613      */
1614     if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_GENERIC)) {
1615         gtk_item_factory_create_item(main_menu_factory, sep_entry, NULL, 2);
1616     }
1617     if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_CONVERSATION_LIST)) {
1618         /*gtk_item_factory_create_item(main_menu_factory, sep_entry, NULL, 2);*/
1619     }
1620     if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_ENDPOINT_LIST)) {
1621         /*gtk_item_factory_create_item(main_menu_factory, sep_entry, NULL, 2);*/
1622     }
1623     if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_RESPONSE_TIME)) {
1624         gtk_item_factory_create_item(main_menu_factory, sep_entry, NULL, 2);
1625     }
1626     if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_TELEPHONY)) {
1627         /*gtk_item_factory_create_item(main_menu_factory, sep_entry, NULL, 2);*/
1628     }
1629     if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_UNSORTED)) {
1630         /*gtk_item_factory_create_item(main_menu_factory, sep_entry, NULL, 2);*/
1631     }
1632     if (merge_tap_menus_layered(node, REGISTER_ANALYZE_GROUP_UNSORTED)) {
1633         sep_entry->path = "/Analyze/";
1634         /*gtk_item_factory_create_item(main_menu_factory, sep_entry, NULL, 2);*/
1635     }
1636     if (merge_tap_menus_layered(node, REGISTER_ANALYZE_GROUP_CONVERSATION_FILTER)) {
1637         sep_entry->path = "/Analyze/Conversation Filter/";
1638         /*gtk_item_factory_create_item(main_menu_factory, sep_entry, NULL, 2);*/
1639     }
1640     if (merge_tap_menus_layered(node, REGISTER_TOOLS_GROUP_UNSORTED)) {
1641         /*gtk_item_factory_create_item(main_menu_factory, sep_entry, NULL, 2);*/
1642     }
1643
1644     g_free (sep_entry);
1645 }
1646
1647
1648
1649 /*
1650  * Enable/disable menu sensitivity.
1651  */
1652 static void
1653 set_menu_sensitivity(GtkItemFactory *ifactory, const gchar *path, gint val)
1654 {
1655     GSList *menu_list;
1656     GtkWidget *menu_item;
1657     gchar *dup;
1658     gchar *dest;
1659
1660
1661     /* the underscore character regularly confuses things, as it will prevent finding
1662      * the menu_item, so it has to be removed first */
1663     dup = g_strdup(path);
1664     dest = dup;
1665     while(*path) {
1666         if (*path != '_') {
1667             *dest = *path;
1668             dest++;
1669         }
1670         path++;
1671     }
1672     *dest = '\0';
1673
1674     if (ifactory == NULL) {
1675         /*
1676          * Do it for all pop-up menus.
1677          */
1678         for (menu_list = popup_menu_list; menu_list != NULL;
1679              menu_list = g_slist_next(menu_list))
1680             set_menu_sensitivity(menu_list->data, dup, val);
1681     } else {
1682         /*
1683          * Do it for that particular menu.
1684          */
1685         if ((menu_item = gtk_item_factory_get_widget(ifactory, dup)) != NULL) {
1686             if (GTK_IS_MENU(menu_item)) {
1687                 /*
1688                  * "dup" refers to a submenu; "gtk_item_factory_get_widget()"
1689                  * gets the menu, not the item that, when selected, pops up
1690                  * the submenu.
1691                  *
1692                  * We have to change the latter item's sensitivity, so that
1693                  * it shows up normally if sensitive and grayed-out if
1694                  * insensitive.
1695                  */
1696                 menu_item = gtk_menu_get_attach_widget(GTK_MENU(menu_item));
1697             }
1698             gtk_widget_set_sensitive(menu_item, val);
1699         } else{
1700 #ifndef NEW_PACKET_LIST
1701             /* be sure this menu item *is* existing */
1702             g_assert_not_reached();
1703 #endif
1704         }
1705     }
1706
1707     g_free(dup);
1708 }
1709
1710 static void
1711 set_menu_object_data_meat(GtkItemFactory *ifactory, const gchar *path, const gchar *key, gpointer data)
1712 {
1713     GtkWidget *menu = NULL;
1714
1715     if ((menu = gtk_item_factory_get_widget(ifactory, path)) != NULL)
1716         g_object_set_data(G_OBJECT(menu), key, data);
1717 }
1718
1719 void
1720 set_menu_object_data (const gchar *path, const gchar *key, gpointer data) {
1721     GSList *menu_list = popup_menu_list;
1722     gchar *shortpath = strrchr(path, '/');
1723
1724     set_menu_object_data_meat(main_menu_factory, path, key, data);
1725     while (menu_list != NULL) {
1726         set_menu_object_data_meat(menu_list->data, shortpath, key, data);
1727         set_menu_object_data_meat(menu_list->data, path, key, data);
1728         menu_list = g_slist_next(menu_list);
1729     }
1730 }
1731
1732
1733 /* Recently used capture files submenu:
1734  * Submenu containing the recently used capture files.
1735  * The capture filenames are always kept with the absolute path, to be independant
1736  * of the current path.
1737  * They are only stored inside the labels of the submenu (no separate list). */
1738
1739 #define MENU_RECENT_FILES_PATH "/File/Open Recent"
1740 #define MENU_RECENT_FILES_KEY "Recent File Name"
1741
1742
1743
1744 static void
1745 update_menu_recent_capture_file1(GtkWidget *widget, gpointer cnt) {
1746     gchar *widget_cf_name;
1747
1748     widget_cf_name = g_object_get_data(G_OBJECT(widget), MENU_RECENT_FILES_KEY);
1749
1750     /* if this menu item is a file, count it */
1751     if (widget_cf_name) {
1752         (*(guint *)cnt)++;
1753         main_welcome_add_recent_capture_files(widget_cf_name);
1754     }
1755 }
1756
1757
1758
1759 /* update the menu */
1760 static void
1761 update_menu_recent_capture_file(GtkWidget *submenu_recent_files) {
1762     guint cnt = 0;
1763
1764
1765     main_welcome_reset_recent_capture_files();
1766
1767     gtk_container_foreach(GTK_CONTAINER(submenu_recent_files),
1768                           update_menu_recent_capture_file1, &cnt);
1769
1770     /* make parent menu item sensitive only, if we have any valid files in the list */
1771     set_menu_sensitivity(main_menu_factory, MENU_RECENT_FILES_PATH, cnt);
1772 }
1773
1774
1775
1776 /* remove the capture filename from the "Recent Files" menu */
1777 static void
1778 remove_menu_recent_capture_filename(gchar *cf_name) {
1779     GtkWidget *submenu_recent_files;
1780     GList* child_list;
1781     GList* child_list_item;
1782     GtkWidget    *menu_item_child;
1783     const gchar *menu_item_cf_name;
1784     
1785
1786     /* get the submenu container item */
1787     submenu_recent_files = gtk_item_factory_get_widget(main_menu_factory, MENU_RECENT_FILES_PATH);
1788
1789     /* find the corresponding menu item to be removed */
1790     child_list = gtk_container_get_children(GTK_CONTAINER(submenu_recent_files));
1791     child_list_item = child_list;
1792     while(child_list_item) {
1793         menu_item_child = (GTK_BIN(child_list_item->data))->child;
1794         if (menu_item_child != NULL) { /* Note: there are two "extra" items on the end of the child_list: */
1795                                        /*  - a separator (with no menu_item_child and thus no text label) */
1796                                        /*  - a 2nd item with a menu_child with text label "Clear"         */
1797                                        /*       [See add_menu_recent_capture_file_absolute() ]            */
1798                                        /* 'if (menu_item_child != NULL)' skips the separator item;        */
1799                                        /* An absolute filename in cf_name will never match  "Clear".      */
1800             menu_item_cf_name = gtk_label_get_text(GTK_LABEL(menu_item_child));
1801             if(strcmp(menu_item_cf_name, cf_name) == 0) {
1802                 /* XXX: is this all we need to do, to free the menu item and its label?
1803                    The reference count of widget will go to 0, so it'll be freed;
1804                    will that free the label? */
1805                 gtk_container_remove(GTK_CONTAINER(submenu_recent_files), child_list_item->data);
1806             }
1807         }
1808         child_list_item = g_list_next(child_list_item);
1809     }
1810     g_list_free(child_list);
1811
1812     update_menu_recent_capture_file(submenu_recent_files);
1813 }
1814
1815
1816 /* remove the capture filename from the "Recent Files" menu */
1817 static void
1818 remove_menu_recent_capture_file(GtkWidget *widget, gpointer unused _U_) {
1819     GtkWidget *submenu_recent_files;
1820     gchar *widget_cf_name;
1821
1822
1823     widget_cf_name = g_object_get_data(G_OBJECT(widget), MENU_RECENT_FILES_KEY);
1824     g_free(widget_cf_name);
1825
1826     /* get the submenu container item */
1827     submenu_recent_files = gtk_item_factory_get_widget(main_menu_factory, MENU_RECENT_FILES_PATH);
1828
1829     /* XXX: is this all we need to do, to free the menu item and its label?
1830        The reference count of widget will go to 0, so it'll be freed;
1831        will that free the label? */
1832     gtk_container_remove(GTK_CONTAINER(submenu_recent_files), widget);
1833 }
1834
1835
1836 /* callback, if the user pushed the <Clear> menu item */
1837 static void
1838 clear_menu_recent_capture_file_cmd_cb(GtkWidget *w _U_, gpointer unused _U_) {
1839     GtkWidget *submenu_recent_files;
1840
1841
1842     submenu_recent_files = gtk_item_factory_get_widget(main_menu_factory, MENU_RECENT_FILES_PATH);
1843
1844     gtk_container_foreach(GTK_CONTAINER(submenu_recent_files),
1845                           remove_menu_recent_capture_file, NULL);
1846
1847     update_menu_recent_capture_file(submenu_recent_files);
1848 }
1849
1850
1851 /* Open a file by it's name
1852    (Beware: will not ask to close existing capture file!) */
1853 void
1854 menu_open_filename(gchar *cf_name)
1855 {
1856     GtkWidget *submenu_recent_files;
1857     int       err;
1858
1859     submenu_recent_files = gtk_item_factory_get_widget(main_menu_factory, MENU_RECENT_FILES_PATH);
1860
1861     /* open and read the capture file (this will close an existing file) */
1862     if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
1863         cf_read(&cfile, FALSE);
1864     } else {
1865         /* the capture file apparently no longer exists; remove menu item    */
1866         /* XXX: ask user to remove item, it's maybe only a temporary problem */
1867         remove_menu_recent_capture_filename(cf_name);
1868     }
1869
1870     update_menu_recent_capture_file(submenu_recent_files);
1871 }
1872
1873
1874 /* callback, if the user pushed a recent file submenu item */
1875 void
1876 menu_open_recent_file_cmd(GtkWidget *w)
1877 {
1878     GtkWidget   *submenu_recent_files;
1879     GtkWidget   *menu_item_child;
1880     const gchar *cf_name;
1881     int         err;
1882
1883     submenu_recent_files = gtk_item_factory_get_widget(main_menu_factory, MENU_RECENT_FILES_PATH);
1884
1885     /* get capture filename from the menu item label */
1886     menu_item_child = (GTK_BIN(w))->child;
1887     cf_name = gtk_label_get_text(GTK_LABEL(menu_item_child));
1888
1889     /* open and read the capture file (this will close an existing file) */
1890     if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
1891         cf_read(&cfile, FALSE);
1892     } else {
1893         /* the capture file apparently no longer exists; remove menu item    */
1894         /* XXX: ask user to remove item, it's maybe only a temporary problem */
1895         remove_menu_recent_capture_file(w, NULL);
1896     }
1897
1898     update_menu_recent_capture_file(submenu_recent_files);
1899 }
1900
1901 static void menu_open_recent_file_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
1902 {
1903     switch(btn) {
1904     case(ESD_BTN_YES):
1905         /* save file first */
1906         file_save_as_cmd(after_save_open_recent_file, data);
1907         break;
1908     case(ESD_BTN_NO):
1909         cf_close(&cfile);
1910         menu_open_recent_file_cmd(data);
1911         break;
1912     case(ESD_BTN_CANCEL):
1913         break;
1914     default:
1915         g_assert_not_reached();
1916     }
1917 }
1918
1919 static void
1920 menu_open_recent_file_cmd_cb(GtkWidget *widget, gpointer data _U_) {
1921     gpointer  dialog;
1922
1923
1924     if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
1925         /* user didn't saved his current file, ask him */
1926         dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO_CANCEL,
1927                                "%sSave capture file before opening a new one?%s\n\n"
1928                                "If you open a new capture file without saving, your current capture data will be discarded.",
1929                                simple_dialog_primary_start(), simple_dialog_primary_end());
1930         simple_dialog_set_cb(dialog, menu_open_recent_file_answered_cb, widget);
1931     } else {
1932         /* unchanged file */
1933         menu_open_recent_file_cmd(widget);
1934     }
1935 }
1936
1937 /* add the capture filename (with an absolute path) to the "Recent Files" menu */
1938 static void
1939 add_menu_recent_capture_file_absolute(gchar *cf_name) {
1940     GtkWidget *submenu_recent_files;
1941     GList *menu_item_list;
1942     GList *li;
1943     gchar *widget_cf_name;
1944     gchar *normalized_cf_name;
1945     GtkWidget *menu_item;
1946     guint cnt;
1947
1948
1949
1950     normalized_cf_name = g_strdup(cf_name);
1951 #ifdef _WIN32
1952     /* replace all slashes by backslashes */
1953     g_strdelimit(normalized_cf_name, "/", '\\');
1954 #endif
1955
1956     /* get the submenu container item */
1957     submenu_recent_files = gtk_item_factory_get_widget(main_menu_factory, MENU_RECENT_FILES_PATH);
1958
1959     /* convert container to a GList */
1960     menu_item_list = gtk_container_get_children(GTK_CONTAINER(submenu_recent_files));
1961
1962     /* iterate through list items of menu_item_list,
1963      * removing special items, a maybe duplicate entry and every item above count_max */
1964     cnt = 1;
1965     for (li = g_list_first(menu_item_list); li; li = li->next, cnt++) {
1966         /* get capture filename */
1967         menu_item = GTK_WIDGET(li->data);
1968         widget_cf_name = g_object_get_data(G_OBJECT(menu_item), MENU_RECENT_FILES_KEY);
1969
1970         /* if this element string is one of our special items (seperator, ...) or
1971          * already in the list or
1972          * this element is above maximum count (too old), remove it */
1973         if (!widget_cf_name ||
1974 #ifdef _WIN32
1975             /* do a case insensitive compare on win32 */
1976             g_ascii_strncasecmp(widget_cf_name, normalized_cf_name, 1000) == 0 ||
1977 #else   /* _WIN32 */
1978             /* do a case sensitive compare on unix */
1979             strncmp(widget_cf_name, normalized_cf_name, 1000) == 0 ||
1980 #endif
1981             cnt >= prefs.gui_recent_files_count_max) {
1982             remove_menu_recent_capture_file(li->data, NULL);
1983             cnt--;
1984         }
1985     }
1986
1987     g_list_free(menu_item_list);
1988
1989     /* add new item at latest position */
1990     menu_item = gtk_menu_item_new_with_label(normalized_cf_name);
1991     g_object_set_data(G_OBJECT(menu_item), MENU_RECENT_FILES_KEY, normalized_cf_name);
1992     gtk_menu_shell_prepend (GTK_MENU_SHELL(submenu_recent_files), menu_item);
1993     g_signal_connect_swapped(GTK_OBJECT(menu_item), "activate",
1994                              G_CALLBACK(menu_open_recent_file_cmd_cb), (GtkObject *) menu_item);
1995     gtk_widget_show (menu_item);
1996
1997     /* add seperator at last position */
1998     menu_item = gtk_menu_item_new();
1999     gtk_menu_shell_append (GTK_MENU_SHELL(submenu_recent_files), menu_item);
2000     gtk_widget_show (menu_item);
2001
2002     /* add new "clear list" item at last position */
2003     menu_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_CLEAR, NULL);
2004     gtk_menu_shell_append (GTK_MENU_SHELL(submenu_recent_files), menu_item);
2005     g_signal_connect_swapped(GTK_OBJECT(menu_item), "activate",
2006                              G_CALLBACK(clear_menu_recent_capture_file_cmd_cb), (GtkObject *) menu_item);
2007     gtk_widget_show (menu_item);
2008
2009     update_menu_recent_capture_file(submenu_recent_files);
2010 }
2011
2012
2013 /* add the capture filename to the "Recent Files" menu */
2014 /* (will change nothing, if this filename is already in the menu) */
2015 /*
2016  * XXX - We might want to call SHAddToRecentDocs under Windows 7:
2017  * http://stackoverflow.com/questions/437212/how-do-you-register-a-most-recently-used-list-with-windows-in-preparation-for-win
2018  */
2019 void
2020 add_menu_recent_capture_file(gchar *cf_name) {
2021     gchar *curr;
2022     gchar *absolute;
2023
2024
2025     /* if this filename is an absolute path, we can use it directly */
2026     if (g_path_is_absolute(cf_name)) {
2027         add_menu_recent_capture_file_absolute(cf_name);
2028         return;
2029     }
2030
2031     /* this filename is not an absolute path, prepend the current dir */
2032     curr = g_get_current_dir();
2033     absolute = g_strdup_printf("%s%s%s", curr, G_DIR_SEPARATOR_S, cf_name);
2034     add_menu_recent_capture_file_absolute(absolute);
2035     g_free(curr);
2036     g_free(absolute);
2037 }
2038
2039
2040 /* write all capture filenames of the menu to the user's recent file */
2041 void
2042 menu_recent_file_write_all(FILE *rf) {
2043     GtkWidget   *submenu_recent_files;
2044     GList       *children;
2045     GList       *child;
2046     gchar       *cf_name;
2047
2048
2049     submenu_recent_files = gtk_item_factory_get_widget(main_menu_factory, MENU_RECENT_FILES_PATH);
2050
2051     /* we have to iterate backwards through the children's list,
2052      * so we get the latest item last in the file.
2053      * (don't use gtk_container_foreach() here, it will return the wrong iteration order) */
2054     children = gtk_container_get_children(GTK_CONTAINER(submenu_recent_files));
2055     child = g_list_last(children);
2056     while(child != NULL) {
2057         /* get capture filename from the menu item label */
2058         cf_name = g_object_get_data(G_OBJECT(child->data), MENU_RECENT_FILES_KEY);
2059         if (cf_name) {
2060             if(u3_active())
2061                 fprintf (rf, RECENT_KEY_CAPTURE_FILE ": %s\n", u3_contract_device_path(cf_name));
2062             else
2063                 fprintf (rf, RECENT_KEY_CAPTURE_FILE ": %s\n", cf_name);
2064         }
2065
2066         child = g_list_previous(child);
2067     }
2068
2069     g_list_free(children);
2070 }
2071
2072
2073 static void
2074 show_hide_cb(GtkWidget *w, gpointer data _U_, gint action)
2075 {
2076
2077     /* save current setting in recent */
2078     switch(action) {
2079         case(SHOW_HIDE_MAIN_TOOLBAR):
2080         recent.main_toolbar_show = GTK_CHECK_MENU_ITEM(w)->active;
2081         break;
2082         case(SHOW_HIDE_FILTER_TOOLBAR):
2083         recent.filter_toolbar_show = GTK_CHECK_MENU_ITEM(w)->active;
2084         break;
2085 #ifdef HAVE_AIRPCAP
2086         case(SHOW_HIDE_AIRPCAP_TOOLBAR):
2087         recent.airpcap_toolbar_show = GTK_CHECK_MENU_ITEM(w)->active;
2088         break;
2089 #endif
2090         case(SHOW_HIDE_STATUSBAR):
2091         recent.statusbar_show = GTK_CHECK_MENU_ITEM(w)->active;
2092         break;
2093         case(SHOW_HIDE_PACKET_LIST):
2094         recent.packet_list_show = GTK_CHECK_MENU_ITEM(w)->active;
2095         break;
2096         case(SHOW_HIDE_TREE_VIEW):
2097         recent.tree_view_show = GTK_CHECK_MENU_ITEM(w)->active;
2098         break;
2099         case(SHOW_HIDE_BYTE_VIEW):
2100         recent.byte_view_show = GTK_CHECK_MENU_ITEM(w)->active;
2101         break;
2102         default:
2103             g_assert_not_reached();
2104     }
2105
2106     main_widgets_show_or_hide();
2107 }
2108
2109
2110 static void
2111 timestamp_format_cb(GtkWidget *w _U_, gpointer d _U_, gint action)
2112 {
2113     if (recent.gui_time_format != action) {
2114         timestamp_set_type(action);
2115         recent.gui_time_format = action;
2116 #ifdef NEW_PACKET_LIST
2117                 /* This call adjusts column width */
2118                 cf_timestamp_auto_precision(&cfile);            
2119                 new_packet_list_queue_draw();
2120 #else
2121         cf_change_time_formats(&cfile);
2122 #endif
2123     }
2124 }
2125
2126
2127 static void
2128 timestamp_precision_cb(GtkWidget *w _U_, gpointer d _U_, gint action)
2129 {
2130     if (recent.gui_time_precision != action) {
2131         /* the actual precision will be set in cf_change_time_formats() below */
2132         if (action == TS_PREC_AUTO) {
2133             timestamp_set_precision(TS_PREC_AUTO_SEC);
2134         } else {
2135             timestamp_set_precision(action);
2136         }
2137         recent.gui_time_precision  = action;
2138 #ifdef NEW_PACKET_LIST
2139                 /* This call adjusts column width */
2140                 cf_timestamp_auto_precision(&cfile);
2141                 new_packet_list_queue_draw();
2142 #else
2143         cf_change_time_formats(&cfile);
2144 #endif
2145     }
2146 }
2147
2148
2149 void
2150 menu_name_resolution_changed(void)
2151 {
2152     GtkWidget *menu = NULL;
2153
2154     menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Name Resolution/Enable for MAC Layer");
2155     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), g_resolv_flags & RESOLV_MAC);
2156
2157     menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Name Resolution/Enable for Network Layer");
2158     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), g_resolv_flags & RESOLV_NETWORK);
2159
2160     menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Name Resolution/Enable for Transport Layer");
2161     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), g_resolv_flags & RESOLV_TRANSPORT);
2162 }
2163
2164 static void
2165 name_resolution_cb(GtkWidget *w, gpointer d _U_, gint action)
2166 {
2167     if (GTK_CHECK_MENU_ITEM(w)->active) {
2168         g_resolv_flags |= action;
2169     } else {
2170         g_resolv_flags &= ~action;
2171     }
2172 }
2173
2174 #ifdef HAVE_LIBPCAP
2175 void
2176 menu_auto_scroll_live_changed(gboolean auto_scroll_live_in) {
2177     GtkWidget *menu;
2178
2179
2180     /* tell menu about it */
2181     menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Auto Scroll in Live Capture");
2182     if( ((gboolean) GTK_CHECK_MENU_ITEM(menu)->active) != auto_scroll_live_in) {
2183         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), auto_scroll_live_in);
2184     }
2185
2186     /* tell toolbar about it */
2187     toolbar_auto_scroll_live_changed(auto_scroll_live_in);
2188
2189     /* change auto scroll */
2190     if(auto_scroll_live_in != auto_scroll_live) {
2191         auto_scroll_live  = auto_scroll_live_in;
2192     }
2193 }
2194
2195 static void
2196 auto_scroll_live_cb(GtkWidget *w _U_, gpointer d _U_)
2197 {
2198     menu_auto_scroll_live_changed(GTK_CHECK_MENU_ITEM(w)->active);
2199 }
2200 #endif
2201
2202
2203 void
2204 menu_colorize_changed(gboolean packet_list_colorize) {
2205     GtkWidget *menu;
2206
2207
2208     /* tell menu about it */
2209     menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Colorize Packet List");
2210     if( ((gboolean) GTK_CHECK_MENU_ITEM(menu)->active) != packet_list_colorize) {
2211         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), packet_list_colorize);
2212     }
2213
2214     /* tell toolbar about it */
2215     toolbar_colorize_changed(packet_list_colorize);
2216
2217     /* change colorization */
2218     if(packet_list_colorize != recent.packet_list_colorize) {
2219         recent.packet_list_colorize = packet_list_colorize;
2220         color_filters_enable(packet_list_colorize);
2221 #ifdef NEW_PACKET_LIST
2222                 new_packet_list_colorize_packets();
2223 #else
2224         cf_colorize_packets(&cfile);
2225 #endif
2226     }
2227 }
2228
2229 static void
2230 colorize_cb(GtkWidget *w, gpointer d _U_)
2231 {
2232     menu_colorize_changed(GTK_CHECK_MENU_ITEM(w)->active);
2233 }
2234
2235
2236 /* the recent file read has finished, update the menu corresponding */
2237 void
2238 menu_recent_read_finished(void) {
2239     GtkWidget *menu = NULL;
2240
2241     menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Main Toolbar");
2242     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), recent.main_toolbar_show);
2243
2244     menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Filter Toolbar");
2245     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), recent.filter_toolbar_show);
2246
2247 #ifdef HAVE_AIRPCAP
2248     menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Wireless Toolbar");
2249     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), recent.airpcap_toolbar_show);
2250 #endif
2251
2252     menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Statusbar");
2253     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), recent.statusbar_show);
2254
2255     menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Packet List");
2256     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), recent.packet_list_show);
2257
2258     menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Packet Details");
2259     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), recent.tree_view_show);
2260
2261     menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Packet Bytes");
2262     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), recent.byte_view_show);
2263
2264     menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Colorize Packet List");
2265     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), recent.packet_list_colorize);
2266
2267     menu_name_resolution_changed();
2268
2269 #ifdef HAVE_LIBPCAP
2270     menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Auto Scroll in Live Capture");
2271     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), auto_scroll_live);
2272 #endif
2273
2274     main_widgets_rearrange();
2275
2276     /* don't change the time format, if we had a command line value */
2277     if (timestamp_get_type() != TS_NOT_SET) {
2278         recent.gui_time_format = timestamp_get_type();
2279     }
2280
2281     switch(recent.gui_time_format) {
2282     case(TS_ABSOLUTE_WITH_DATE):
2283         menu = gtk_item_factory_get_widget(main_menu_factory,
2284             "/View/Time Display Format/Date and Time of Day:   1970-01-01 01:02:03.123456");
2285         break;
2286     case(TS_ABSOLUTE):
2287         menu = gtk_item_factory_get_widget(main_menu_factory,
2288             "/View/Time Display Format/Time of Day:   01:02:03.123456");
2289         break;
2290     case(TS_RELATIVE):
2291         menu = gtk_item_factory_get_widget(main_menu_factory,
2292             "/View/Time Display Format/Seconds Since Beginning of Capture:   123.123456");
2293         break;
2294     case(TS_DELTA):
2295         menu = gtk_item_factory_get_widget(main_menu_factory,
2296             "/View/Time Display Format/Seconds Since Previous Captured Packet:   1.123456");
2297         break;
2298     case(TS_DELTA_DIS):
2299         menu = gtk_item_factory_get_widget(main_menu_factory,
2300             "/View/Time Display Format/Seconds Since Previous Displayed Packet:   1.123456");
2301         break;
2302     case(TS_EPOCH):
2303         menu = gtk_item_factory_get_widget(main_menu_factory,
2304             "/View/Time Display Format/Seconds Since Epoch (1970-01-01):   1234567890.123456");
2305         break;
2306     default:
2307         g_assert_not_reached();
2308     }
2309
2310     /* set_active will not trigger the callback when activating an active item! */
2311     recent.gui_time_format = -1;
2312     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), FALSE);
2313     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE);
2314
2315     switch(recent.gui_time_precision) {
2316     case(TS_PREC_AUTO):
2317         menu = gtk_item_factory_get_widget(main_menu_factory,
2318             "/View/Time Display Format/Automatic (File Format Precision)");
2319         break;
2320     case(TS_PREC_FIXED_SEC):
2321         menu = gtk_item_factory_get_widget(main_menu_factory,
2322             "/View/Time Display Format/Seconds:   0");
2323         break;
2324     case(TS_PREC_FIXED_DSEC):
2325         menu = gtk_item_factory_get_widget(main_menu_factory,
2326             "/View/Time Display Format/Deciseconds:   0.1");
2327         break;
2328     case(TS_PREC_FIXED_CSEC):
2329         menu = gtk_item_factory_get_widget(main_menu_factory,
2330             "/View/Time Display Format/Centiseconds:   0.12");
2331         break;
2332     case(TS_PREC_FIXED_MSEC):
2333         menu = gtk_item_factory_get_widget(main_menu_factory,
2334             "/View/Time Display Format/Milliseconds:   0.123");
2335         break;
2336     case(TS_PREC_FIXED_USEC):
2337         menu = gtk_item_factory_get_widget(main_menu_factory,
2338             "/View/Time Display Format/Microseconds:   0.123456");
2339         break;
2340     case(TS_PREC_FIXED_NSEC):
2341         menu = gtk_item_factory_get_widget(main_menu_factory,
2342             "/View/Time Display Format/Nanoseconds:   0.123456789");
2343         break;
2344     default:
2345         g_assert_not_reached();
2346     }
2347
2348     /* set_active will not trigger the callback when activating an active item! */
2349     recent.gui_time_precision = -1;
2350     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), FALSE);
2351     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE);
2352
2353     menu_colorize_changed(recent.packet_list_colorize);
2354
2355     switch (recent.gui_bytes_view) {
2356     case BYTES_HEX:
2357         menu = gtk_item_factory_get_widget(bytes_menu_factory, "/Hex View");
2358         break;
2359     case BYTES_BITS:
2360         menu = gtk_item_factory_get_widget(bytes_menu_factory, "/Bits View");
2361         break;
2362     default:
2363         g_assert_not_reached();
2364     }
2365     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE);
2366 }
2367
2368
2369 gint
2370 popup_menu_handler(GtkWidget *widget, GdkEvent *event, gpointer data)
2371 {
2372     GtkWidget *menu = (GtkWidget *)data;
2373     GdkEventButton *event_button = NULL;
2374     gint row, column;
2375
2376     if(widget == NULL || event == NULL || data == NULL) {
2377         return FALSE;
2378     }
2379
2380     /*
2381      * If we ever want to make the menu differ based on what row
2382      * and/or column we're above, we'd use "eth_clist_get_selection_info()"
2383      * to find the row and column number for the coordinates; a CTree is,
2384      * I guess, like a CList with one column(?) and the expander widget
2385      * as a pixmap.
2386      */
2387     /* Check if we are on packet_list object */
2388     if (widget == g_object_get_data(G_OBJECT(popup_menu_object), E_MPACKET_LIST_KEY) &&
2389         ((GdkEventButton *)event)->button != 1) {
2390 #ifdef NEW_PACKET_LIST
2391         gint physical_row;
2392         if (new_packet_list_get_event_row_column((GdkEventButton *)event, &physical_row, &row, &column)) {
2393 #else
2394         if (packet_list_get_event_row_column(widget, (GdkEventButton *)event, &row, &column)) {
2395 #endif
2396             g_object_set_data(G_OBJECT(popup_menu_object), E_MPACKET_LIST_ROW_KEY,
2397 #ifdef NEW_PACKET_LIST
2398                             GINT_TO_POINTER(physical_row));
2399 #else
2400                             GINT_TO_POINTER(row));
2401 #endif
2402             g_object_set_data(G_OBJECT(popup_menu_object), E_MPACKET_LIST_COL_KEY,
2403                             GINT_TO_POINTER(column));
2404 #ifdef NEW_PACKET_LIST
2405             new_packet_list_set_selected_row(row);
2406 #else
2407             packet_list_set_selected_row(row);
2408 #endif
2409         }
2410     }
2411
2412     /* Check if we are on tree_view object */
2413     if (widget == tree_view) {
2414         tree_view_select(widget, (GdkEventButton *) event);
2415     }
2416
2417     /* context menu handler */
2418     if(event->type == GDK_BUTTON_PRESS) {
2419         event_button = (GdkEventButton *) event;
2420
2421         /* To qoute the "Gdk Event Structures" doc:
2422          * "Normally button 1 is the left mouse button, 2 is the middle button, and 3 is the right button" */
2423         if(event_button->button == 3) {
2424             gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
2425                            event_button->button,
2426                            event_button->time);
2427             g_signal_stop_emission_by_name(widget, "button_press_event");
2428             return TRUE;
2429         }
2430     }
2431
2432     /* Check if we are on byte_view object */
2433     if(widget == get_notebook_bv_ptr(byte_nb_ptr)) {
2434         byte_view_select(widget, (GdkEventButton *) event);
2435     }
2436
2437     /* GDK_2BUTTON_PRESS is a doubleclick -> expand/collapse tree row */
2438     /* GTK version 1 seems to be doing this automatically */
2439     if (widget == tree_view && event->type == GDK_2BUTTON_PRESS) {
2440         GtkTreePath      *path;
2441
2442         if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget),
2443                                           (gint) (((GdkEventButton *)event)->x),
2444                                           (gint) (((GdkEventButton *)event)->y),
2445                                           &path, NULL, NULL, NULL))
2446         {
2447             if (gtk_tree_view_row_expanded(GTK_TREE_VIEW(widget), path))
2448                 gtk_tree_view_collapse_row(GTK_TREE_VIEW(widget), path);
2449             else
2450                 gtk_tree_view_expand_row(GTK_TREE_VIEW(widget), path,
2451                                          FALSE);
2452             gtk_tree_path_free(path);
2453         }
2454     }
2455     return FALSE;
2456 }
2457
2458 /* Enable or disable menu items based on whether you have a capture file
2459    you've finished reading and, if you have one, whether it's been saved
2460    and whether it could be saved except by copying the raw packet data. */
2461 void
2462 set_menus_for_capture_file(capture_file *cf)
2463 {
2464     if (cf == NULL) {
2465         /* We have no capture file */
2466         set_menu_sensitivity(main_menu_factory, "/File/Merge...", FALSE);
2467         set_menu_sensitivity(main_menu_factory, "/File/Close", FALSE);
2468         set_menu_sensitivity(main_menu_factory, "/File/Save", FALSE);
2469         set_menu_sensitivity(main_menu_factory, "/File/Save As...", FALSE);
2470         set_menu_sensitivity(main_menu_factory, "/File/Export", FALSE);
2471         set_menu_sensitivity(main_menu_factory, "/View/Reload", FALSE);
2472         set_toolbar_for_capture_file(FALSE);
2473         set_toolbar_for_unsaved_capture_file(FALSE);
2474     } else {
2475         set_menu_sensitivity(main_menu_factory, "/File/Merge...", TRUE);
2476         set_menu_sensitivity(main_menu_factory, "/File/Close", TRUE);
2477         set_menu_sensitivity(main_menu_factory, "/File/Save", !cf->user_saved);
2478         /*
2479          * "Save As..." works only if we can write the file out in at least
2480          * one format (so we can save the whole file or just a subset) or
2481          * if we have an unsaved capture (so writing the whole file out
2482          * with a raw data copy makes sense).
2483          */
2484         set_menu_sensitivity(main_menu_factory, "/File/Save As...",
2485                              cf_can_save_as(cf) || !cf->user_saved);
2486         set_menu_sensitivity(main_menu_factory, "/File/Export", TRUE);
2487         set_menu_sensitivity(main_menu_factory, "/View/Reload", TRUE);
2488         set_toolbar_for_unsaved_capture_file(!cf->user_saved);
2489         set_toolbar_for_capture_file(TRUE);
2490     }
2491 }
2492
2493 /* Enable or disable menu items based on whether there's a capture in
2494    progress. */
2495 void
2496 set_menus_for_capture_in_progress(gboolean capture_in_progress)
2497 {
2498     set_menu_sensitivity(main_menu_factory, "/File/Open...",
2499                          !capture_in_progress);
2500     set_menu_sensitivity(main_menu_factory, "/File/Open Recent",
2501                          !capture_in_progress);
2502     set_menu_sensitivity(main_menu_factory, "/File/Export",
2503                          capture_in_progress);
2504 #ifdef HAVE_LIBPCAP
2505     set_menu_sensitivity(main_menu_factory, "/Capture/Options...",
2506                          !capture_in_progress);
2507     set_menu_sensitivity(main_menu_factory, "/Capture/Start",
2508                          !capture_in_progress);
2509     set_menu_sensitivity(main_menu_factory, "/Capture/Stop",
2510                          capture_in_progress);
2511     set_menu_sensitivity(main_menu_factory, "/Capture/Restart",
2512                          capture_in_progress);
2513     set_toolbar_for_capture_in_progress(capture_in_progress);
2514
2515     set_capture_if_dialog_for_capture_in_progress(capture_in_progress);
2516 #endif /* HAVE_LIBPCAP */
2517 }
2518
2519 /* Enable or disable menu items based on whether you have some captured
2520    packets. */
2521 static gboolean
2522 walk_menu_tree_for_captured_packets(GList *node,
2523     gboolean have_captured_packets)
2524 {
2525     gboolean    is_enabled;
2526     GList       *child;
2527     menu_item_t *node_data = node->data;
2528
2529     /*
2530      * Is this a leaf node or an interior node?
2531      */
2532     if (node_data->children == NULL) {
2533         /*
2534          * It's a leaf node.
2535          *
2536          * If it has no "selected_packet_enabled()" or
2537          * "selected_tree_row_enabled()" routines, we enable
2538          * it.  This allows tap windows to be popped up even
2539          * if you have no capture file; this is done to let
2540          * the user pop up multiple tap windows before reading
2541          * in a capture file, so that they can be processed in
2542          * parallel while the capture file is being read rather
2543          * than one at at time as you pop up the windows, and to
2544          * let the user pop up tap windows before starting an
2545          * "Update list of packets in real time" capture, so that
2546          * the statistics can be displayed while the capture is
2547          * in progress.
2548          *
2549          * If it has either of those routines, we disable it for
2550          * now - as long as, when a capture is first available,
2551          * we don't get called after a packet or tree row is
2552          * selected, that's OK.
2553          * XXX - that should be done better.
2554          */
2555         if (node_data->selected_packet_enabled == NULL &&
2556             node_data->selected_tree_row_enabled == NULL)
2557             node_data->enabled = TRUE;
2558         else
2559             node_data->enabled = FALSE;
2560     } else {
2561         /*
2562          * It's an interior node; call
2563          * "walk_menu_tree_for_captured_packets()" on all its
2564          * children and, if any of them are enabled, enable
2565          * this node, otherwise disable it.
2566          *
2567          * XXX - should we just leave all interior nodes enabled?
2568          * Which is a better UI choice?
2569          */
2570         is_enabled = FALSE;
2571         for (child = node_data->children; child != NULL; child =
2572                  child->next) {
2573             if (walk_menu_tree_for_captured_packets(child,
2574                                                     have_captured_packets))
2575                 is_enabled = TRUE;
2576         }
2577         node_data->enabled = is_enabled;
2578     }
2579
2580     /*
2581      * The root node doesn't correspond to a menu tree item; it
2582      * has a null name pointer.
2583      */
2584     if (node_data->name != NULL) {
2585         set_menu_sensitivity(main_menu_factory, node_data->name,
2586                              node_data->enabled);
2587     }
2588     return node_data->enabled;
2589 }
2590
2591 void
2592 set_menus_for_captured_packets(gboolean have_captured_packets)
2593 {
2594     set_menu_sensitivity(main_menu_factory, "/File/Print...",
2595                          have_captured_packets);
2596     set_menu_sensitivity(packet_list_menu_factory, "/Print...",
2597                          have_captured_packets);
2598     set_menu_sensitivity(main_menu_factory, "/Edit/Find Packet...",
2599                          have_captured_packets);
2600     set_menu_sensitivity(main_menu_factory, "/Edit/Find Next",
2601                          have_captured_packets);
2602     set_menu_sensitivity(main_menu_factory, "/Edit/Find Previous",
2603                          have_captured_packets);
2604     set_menu_sensitivity(main_menu_factory, "/View/Zoom In",
2605                          have_captured_packets);
2606     set_menu_sensitivity(main_menu_factory, "/View/Zoom Out",
2607                          have_captured_packets);
2608     set_menu_sensitivity(main_menu_factory, "/View/Normal Size",
2609                          have_captured_packets);
2610     set_menu_sensitivity(main_menu_factory, "/Go/Go to Packet...",
2611                          have_captured_packets);
2612     set_menu_sensitivity(main_menu_factory, "/Go/Previous Packet",
2613                          have_captured_packets);
2614     set_menu_sensitivity(main_menu_factory, "/Go/Next Packet",
2615                          have_captured_packets);
2616     set_menu_sensitivity(main_menu_factory, "/Go/First Packet",
2617                          have_captured_packets);
2618     set_menu_sensitivity(main_menu_factory, "/Go/Last Packet",
2619                          have_captured_packets);
2620     set_menu_sensitivity(main_menu_factory, "/Statistics/Summary",
2621                          have_captured_packets);
2622     set_menu_sensitivity(main_menu_factory, "/Statistics/Protocol Hierarchy",
2623                          have_captured_packets);
2624
2625     walk_menu_tree_for_captured_packets(tap_menu_tree_root,
2626                                         have_captured_packets);
2627     set_toolbar_for_captured_packets(have_captured_packets);
2628 }
2629
2630 /* Enable or disable menu items based on whether a packet is selected and,
2631    if so, on the properties of the packet. */
2632 static gboolean
2633 walk_menu_tree_for_selected_packet(GList *node, frame_data *fd,
2634     epan_dissect_t *edt)
2635 {
2636     gboolean is_enabled;
2637     GList *child;
2638     menu_item_t *node_data = node->data;
2639
2640     /*
2641      * Is this a leaf node or an interior node?
2642      */
2643     if (node_data->children == NULL) {
2644         /*
2645          * It's a leaf node.
2646          *
2647          * If it has no "selected_packet_enabled()" routine,
2648          * leave its enabled/disabled status alone - it
2649          * doesn't depend on whether we have a packet selected
2650          * or not or on the selected packet.
2651          *
2652          * If it has a "selected_packet_enabled()" routine,
2653          * call it and set the item's enabled/disabled status
2654          * based on its return value.
2655          */
2656         if (node_data->selected_packet_enabled != NULL)
2657             node_data->enabled = node_data->selected_packet_enabled(fd, edt, node_data->callback_data);
2658     } else {
2659         /*
2660          * It's an interior node; call
2661          * "walk_menu_tree_for_selected_packet()" on all its
2662          * children and, if any of them are enabled, enable
2663          * this node, otherwise disable it.
2664          *
2665          * XXX - should we just leave all interior nodes enabled?
2666          * Which is a better UI choice?
2667          */
2668         is_enabled = FALSE;
2669         for (child = node_data->children; child != NULL; child =
2670                  child->next) {
2671             if (walk_menu_tree_for_selected_packet(child, fd, edt))
2672                 is_enabled = TRUE;
2673         }
2674         node_data->enabled = is_enabled;
2675     }
2676
2677     /*
2678      * The root node doesn't correspond to a menu tree item; it
2679      * has a null name pointer.
2680      */
2681     if (node_data->name != NULL) {
2682         set_menu_sensitivity(main_menu_factory, node_data->name,
2683                              node_data->enabled);
2684     }
2685     return node_data->enabled;
2686 }
2687
2688 gboolean
2689 packet_is_ssl(epan_dissect_t* edt)
2690 {
2691     GPtrArray* array;
2692     int ssl_id;
2693     gboolean is_ssl;
2694
2695     if (!edt || !edt->tree)
2696         return FALSE;
2697     ssl_id = proto_get_id_by_filter_name("ssl");
2698     if (ssl_id < 0)
2699         return FALSE;
2700     array = proto_find_finfo(edt->tree, ssl_id);
2701     is_ssl = (array->len > 0) ? TRUE : FALSE;
2702     g_ptr_array_free(array, TRUE);
2703     return is_ssl;
2704 }
2705
2706 void
2707 set_menus_for_selected_packet(capture_file *cf)
2708 {
2709     gboolean is_ssl = packet_is_ssl(cf->edt);
2710     set_menu_sensitivity(main_menu_factory, "/Edit/Mark Packet (toggle)",
2711                          cf->current_frame != NULL);
2712     set_menu_sensitivity(packet_list_menu_factory, "/Mark Packet (toggle)",
2713                          cf->current_frame != NULL);
2714     set_menu_sensitivity(main_menu_factory, "/Edit/Find Next Mark",
2715                          cf->current_frame != NULL);
2716     set_menu_sensitivity(main_menu_factory, "/Edit/Find Previous Mark",
2717                          cf->current_frame != NULL);
2718     set_menu_sensitivity(main_menu_factory, "/Edit/Mark All Packets",
2719                          cf->current_frame != NULL);
2720     set_menu_sensitivity(main_menu_factory, "/Edit/Unmark All Packets",
2721                          cf->current_frame != NULL);
2722     set_menu_sensitivity(main_menu_factory, "/Edit/Set Time Reference (toggle)",
2723                          cf->current_frame != NULL);
2724     set_menu_sensitivity(packet_list_menu_factory, "/Set Time Reference (toggle)",
2725                          cf->current_frame != NULL);
2726     set_menu_sensitivity(main_menu_factory, "/Edit/Find Next Reference",
2727                          cf->current_frame != NULL);
2728     set_menu_sensitivity(main_menu_factory, "/Edit/Find Previous Reference",
2729                          cf->current_frame != NULL);
2730     set_menu_sensitivity(main_menu_factory, "/View/Resize All Columns",
2731                          cf->current_frame != NULL);
2732     set_menu_sensitivity(main_menu_factory, "/View/Collapse All",
2733                          cf->current_frame != NULL);
2734     set_menu_sensitivity(tree_view_menu_factory, "/Collapse All",
2735                          cf->current_frame != NULL);
2736     set_menu_sensitivity(main_menu_factory, "/View/Expand All",
2737                          cf->current_frame != NULL);
2738     set_menu_sensitivity(tree_view_menu_factory, "/Expand All",
2739                          cf->current_frame != NULL);
2740     set_menu_sensitivity(main_menu_factory, "/View/Colorize Conversation",
2741                          cf->current_frame != NULL);
2742     set_menu_sensitivity(main_menu_factory, "/View/Reset Coloring 1-10",
2743                          tmp_color_filters_used());
2744     set_menu_sensitivity(main_menu_factory, "/View/Show Packet in New Window",
2745                          cf->current_frame != NULL);
2746     set_menu_sensitivity(packet_list_menu_factory, "/Show Packet in New Window",
2747                          cf->current_frame != NULL);
2748     set_menu_sensitivity(packet_list_menu_factory, "/SCTP",
2749                          cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_SCTP) : FALSE);
2750     set_menu_sensitivity(main_menu_factory, "/Analyze/Follow TCP Stream",
2751                          cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_TCP) : FALSE);
2752     set_menu_sensitivity(packet_list_menu_factory, "/Follow TCP Stream",
2753                          cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_TCP) : FALSE);
2754     set_menu_sensitivity(tree_view_menu_factory, "/Follow TCP Stream",
2755                          cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_TCP) : FALSE);
2756     set_menu_sensitivity(main_menu_factory, "/Analyze/Follow UDP Stream",
2757                          cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_UDP) : FALSE);
2758     set_menu_sensitivity(packet_list_menu_factory, "/Follow UDP Stream",
2759                          cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_UDP) : FALSE);
2760     set_menu_sensitivity(tree_view_menu_factory, "/Follow UDP Stream",
2761                          cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_UDP) : FALSE);
2762     set_menu_sensitivity(main_menu_factory, "/Analyze/Follow SSL Stream",
2763                          cf->current_frame != NULL ? is_ssl : FALSE);
2764     set_menu_sensitivity(packet_list_menu_factory, "/Follow SSL Stream",
2765                          cf->current_frame != NULL ? is_ssl : FALSE);
2766     set_menu_sensitivity(tree_view_menu_factory, "/Follow SSL Stream",
2767                          cf->current_frame != NULL ? is_ssl : FALSE);
2768     set_menu_sensitivity(packet_list_menu_factory, "/Conversation Filter",
2769                          cf->current_frame != NULL);
2770     set_menu_sensitivity(packet_list_menu_factory, "/Conversation Filter/Ethernet",
2771                          cf->current_frame != NULL ? (cf->edt->pi.dl_src.type == AT_ETHER) : FALSE);
2772     set_menu_sensitivity(packet_list_menu_factory, "/Conversation Filter/IP",
2773                          cf->current_frame != NULL ? ((cf->edt->pi.ethertype == ETHERTYPE_IP)||(cf->edt->pi.ethertype == ETHERTYPE_IPv6)) : FALSE);
2774     set_menu_sensitivity(packet_list_menu_factory, "/Conversation Filter/TCP",
2775                          cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_TCP) : FALSE);
2776     set_menu_sensitivity(packet_list_menu_factory, "/Conversation Filter/UDP",
2777                          cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_UDP) : FALSE);
2778     set_menu_sensitivity(packet_list_menu_factory, "/Conversation Filter/PN-CBA Server",
2779                          cf->current_frame != NULL ? (cf->edt->pi.profinet_type != 0 && cf->edt->pi.profinet_type < 10) : FALSE);
2780     set_menu_sensitivity(packet_list_menu_factory, "/Colorize Conversation",
2781                          cf->current_frame != NULL);
2782     set_menu_sensitivity(packet_list_menu_factory, "/Colorize Conversation/Ethernet",
2783                          cf->current_frame != NULL ? (cf->edt->pi.dl_src.type == AT_ETHER) : FALSE);
2784     set_menu_sensitivity(packet_list_menu_factory, "/Colorize Conversation/IP",
2785                          cf->current_frame != NULL ? ((cf->edt->pi.ethertype == ETHERTYPE_IP)||(cf->edt->pi.ethertype == ETHERTYPE_IPv6)) : FALSE);
2786     set_menu_sensitivity(packet_list_menu_factory, "/Colorize Conversation/TCP",
2787                          cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_TCP) : FALSE);
2788     set_menu_sensitivity(packet_list_menu_factory, "/Colorize Conversation/UDP",
2789                          cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_UDP) : FALSE);
2790     set_menu_sensitivity(packet_list_menu_factory, "/Colorize Conversation/PN-CBA Server",
2791                          cf->current_frame != NULL ? (cf->edt->pi.profinet_type != 0 && cf->edt->pi.profinet_type < 10) : FALSE);
2792     set_menu_sensitivity(main_menu_factory, "/Analyze/Decode As...",
2793                          cf->current_frame != NULL && decode_as_ok());
2794     set_menu_sensitivity(packet_list_menu_factory, "/Decode As...",
2795                          cf->current_frame != NULL && decode_as_ok());
2796     set_menu_sensitivity(tree_view_menu_factory, "/Decode As...",
2797                          cf->current_frame != NULL && decode_as_ok());
2798     set_menu_sensitivity(main_menu_factory, "/View/Name Resolution/Resolve Name",
2799                          cf->current_frame != NULL && (g_resolv_flags & RESOLV_ALL_ADDRS) != RESOLV_ALL_ADDRS);
2800     set_menu_sensitivity(tree_view_menu_factory, "/Resolve Name",
2801                          cf->current_frame != NULL && (g_resolv_flags & RESOLV_ALL_ADDRS) != RESOLV_ALL_ADDRS);
2802     set_menu_sensitivity(packet_list_menu_factory, "/Copy",
2803                          cf->current_frame != NULL);
2804     set_menu_sensitivity(packet_list_menu_factory, "/Apply as Filter",
2805                          cf->current_frame != NULL);
2806     set_menu_sensitivity(packet_list_menu_factory, "/Prepare a Filter",
2807                          cf->current_frame != NULL);
2808     set_menu_sensitivity(main_menu_factory, "/Tools/Firewall ACL Rules",
2809                          cf->current_frame != NULL);
2810
2811     walk_menu_tree_for_selected_packet(tap_menu_tree_root, cf->current_frame,
2812                                        cf->edt);
2813 }
2814
2815 /* Enable or disable menu items based on whether a tree row is selected
2816    and, if so, on the properties of the tree row. */
2817 static gboolean
2818 walk_menu_tree_for_selected_tree_row(GList *node, field_info *fi)
2819 {
2820     gboolean is_enabled;
2821     GList *child;
2822     menu_item_t *node_data = node->data;
2823
2824     /*
2825      * Is this a leaf node or an interior node?
2826      */
2827     if (node_data->children == NULL) {
2828         /*
2829          * It's a leaf node.
2830          *
2831          * If it has no "selected_tree_row_enabled()" routine,
2832          * leave its enabled/disabled status alone - it
2833          * doesn't depend on whether we have a tree row selected
2834          * or not or on the selected tree row.
2835          *
2836          * If it has a "selected_tree_row_enabled()" routine,
2837          * call it and set the item's enabled/disabled status
2838          * based on its return value.
2839          */
2840         if (node_data->selected_tree_row_enabled != NULL)
2841             node_data->enabled = node_data->selected_tree_row_enabled(fi, node_data->callback_data);
2842     } else {
2843         /*
2844          * It's an interior node; call
2845          * "walk_menu_tree_for_selected_tree_row()" on all its
2846          * children and, if any of them are enabled, enable
2847          * this node, otherwise disable it.
2848          *
2849          * XXX - should we just leave all interior nodes enabled?
2850          * Which is a better UI choice?
2851          */
2852         is_enabled = FALSE;
2853         for (child = node_data->children; child != NULL; child =
2854                  child->next) {
2855             if (walk_menu_tree_for_selected_tree_row(child, fi))
2856                 is_enabled = TRUE;
2857         }
2858         node_data->enabled = is_enabled;
2859     }
2860
2861     /*
2862      * The root node doesn't correspond to a menu tree item; it
2863      * has a null name pointer.
2864      */
2865     if (node_data->name != NULL) {
2866         set_menu_sensitivity(main_menu_factory, node_data->name,
2867                              node_data->enabled);
2868     }
2869     return node_data->enabled;
2870 }
2871
2872 static void
2873 menu_prefs_toggle_bool (GtkWidget *w, gpointer data)
2874 {
2875     gboolean *value = data;
2876     module_t *module = g_object_get_data (G_OBJECT(w), "module");
2877
2878     module->prefs_changed = TRUE;
2879     *value = !(*value);
2880
2881     prefs_apply (module);
2882     if (!prefs.gui_use_pref_save) {
2883         prefs_main_write();
2884     }
2885     redissect_packets();
2886 }
2887
2888 static void
2889 menu_prefs_change_enum (GtkWidget *w, gpointer data)
2890 {
2891     gint *value = data;
2892     module_t *module = g_object_get_data (G_OBJECT(w), "module");
2893     gint new_value = GPOINTER_TO_INT(g_object_get_data (G_OBJECT(w), "enumval"));
2894
2895     if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM(w)))
2896         return;
2897
2898     if (*value != new_value) {
2899         module->prefs_changed = TRUE;
2900         *value = new_value;
2901
2902         prefs_apply (module);
2903         if (!prefs.gui_use_pref_save) {
2904             prefs_main_write();
2905         }
2906         redissect_packets();
2907     }
2908 }
2909
2910 void
2911 menu_prefs_reset(void)
2912 {
2913         g_free (g_object_get_data(G_OBJECT(tree_view_menu_factory), "menu_abbrev"));
2914         g_object_set_data(G_OBJECT(tree_view_menu_factory), "menu_abbrev", NULL);
2915 }
2916
2917 static void
2918 menu_prefs_change_ok (GtkWidget *w, gpointer parent_w)
2919 {
2920     GtkWidget *entry = g_object_get_data (G_OBJECT(w), "entry");
2921     module_t *module = g_object_get_data (G_OBJECT(w), "module");
2922     pref_t *pref = g_object_get_data (G_OBJECT(w), "pref");
2923     const gchar *new_value =  gtk_entry_get_text(GTK_ENTRY(entry));
2924     range_t *newrange;
2925     gchar *p;
2926     guint uval;
2927
2928     switch (pref->type) {
2929     case PREF_UINT:
2930         uval = strtoul(new_value, &p, pref->info.base);
2931         if (p == new_value || *p != '\0') {
2932             simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2933                           "The value \"%s\" isn't a valid number.",
2934                           new_value);
2935             return;
2936         }
2937         if (*pref->varp.uint != uval) {
2938             module->prefs_changed = TRUE;
2939             *pref->varp.uint = uval;
2940         }
2941         break;
2942     case PREF_STRING:
2943         if (strcmp (*pref->varp.string, new_value) != 0) {
2944             module->prefs_changed = TRUE;
2945             g_free((void*)*pref->varp.string);
2946             *pref->varp.string = g_strdup(new_value);
2947         }
2948         break;
2949     case PREF_RANGE:
2950         if (range_convert_str(&newrange, new_value, pref->info.max_value) != CVT_NO_ERROR) {
2951             simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2952                           "The value \"%s\" isn't a valid range.",
2953                           new_value);
2954             return;
2955         }
2956         if (!ranges_are_equal(*pref->varp.range, newrange)) {
2957             module->prefs_changed = TRUE;
2958             g_free(*pref->varp.range);
2959             *pref->varp.range = newrange;
2960         } else {
2961             g_free (newrange);
2962         }
2963         break;
2964     default:
2965         g_assert_not_reached();
2966         break;
2967     }
2968
2969     if (module->prefs_changed) {
2970         /* Ensure we reload the sub menu */
2971         menu_prefs_reset();
2972         prefs_apply (module);
2973         if (!prefs.gui_use_pref_save) {
2974             prefs_main_write();
2975         }
2976         redissect_packets();
2977     }
2978
2979     window_destroy(GTK_WIDGET(parent_w));
2980 }
2981
2982 static void
2983 menu_prefs_change_cancel (GtkWidget *w _U_, gpointer parent_w)
2984 {
2985     window_destroy(GTK_WIDGET(parent_w));
2986 }
2987
2988 static void 
2989 menu_prefs_edit_dlg (GtkWidget *w, gpointer data)
2990 {
2991     pref_t *pref = data;
2992     module_t *module = g_object_get_data (G_OBJECT(w), "module");
2993     gchar *value = NULL;
2994
2995     GtkWidget *win, *main_tb, *main_vb, *bbox, *cancel_bt, *ok_bt;
2996     GtkWidget *entry, *label;
2997     GtkTooltips *tooltips;
2998
2999     switch (pref->type) {
3000     case PREF_UINT:
3001         switch (pref->info.base) {
3002         case 8:
3003             value = g_strdup_printf("%o", *pref->varp.uint);
3004             break;
3005         case 10:
3006             value = g_strdup_printf("%u", *pref->varp.uint);
3007             break;
3008         case 16:
3009             value = g_strdup_printf("%x", *pref->varp.uint);
3010             break;
3011         default:
3012             g_assert_not_reached();
3013             break;
3014         }
3015         break;
3016     case PREF_STRING:
3017         value = g_strdup(*pref->varp.string);
3018         break;
3019     case PREF_RANGE:
3020         value = g_strdup(range_convert_range (*pref->varp.range));
3021         break;
3022     default:
3023         g_assert_not_reached();
3024         break;
3025     }
3026
3027     tooltips = gtk_tooltips_new();
3028
3029     win = dlg_window_new(module->description);
3030
3031     gtk_window_set_resizable(GTK_WINDOW(win),FALSE);
3032     gtk_window_resize(GTK_WINDOW(win), 400, 100);
3033
3034     main_vb = gtk_vbox_new(FALSE, 5);
3035     gtk_container_add(GTK_CONTAINER(win), main_vb);
3036     gtk_container_set_border_width(GTK_CONTAINER(main_vb), 6);
3037
3038     main_tb = gtk_table_new(2, 2, FALSE);
3039     gtk_box_pack_start(GTK_BOX(main_vb), main_tb, FALSE, FALSE, 0);
3040     gtk_table_set_col_spacings(GTK_TABLE(main_tb), 10);
3041
3042     label = gtk_label_new(ep_strdup_printf("%s:", pref->title));
3043     gtk_table_attach_defaults(GTK_TABLE(main_tb), label, 0, 1, 1, 2);
3044     gtk_misc_set_alignment(GTK_MISC(label), 1.0f, 0.5f);
3045     if (pref->description)
3046         gtk_tooltips_set_tip(tooltips, label, pref->description, NULL);
3047
3048     entry = gtk_entry_new();
3049     gtk_table_attach_defaults(GTK_TABLE(main_tb), entry, 1, 2, 1, 2);
3050     gtk_entry_set_text(GTK_ENTRY(entry), value);
3051     if (pref->description)
3052         gtk_tooltips_set_tip(tooltips, entry, pref->description, NULL);
3053
3054     bbox = dlg_button_row_new(GTK_STOCK_CANCEL,GTK_STOCK_OK, NULL);
3055     gtk_box_pack_end(GTK_BOX(main_vb), bbox, FALSE, FALSE, 0);
3056
3057     ok_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_OK);
3058     g_object_set_data (G_OBJECT(ok_bt), "module", module);
3059     g_object_set_data (G_OBJECT(ok_bt), "entry", entry);
3060     g_object_set_data (G_OBJECT(ok_bt), "pref", pref);
3061     g_signal_connect(ok_bt, "clicked", G_CALLBACK(menu_prefs_change_ok), win);
3062
3063     dlg_set_activate(entry, ok_bt);
3064
3065     cancel_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CANCEL);
3066     g_signal_connect(cancel_bt, "clicked", G_CALLBACK(menu_prefs_change_cancel), win);
3067     window_set_cancel_button(win, cancel_bt, NULL);
3068
3069     gtk_widget_grab_default(ok_bt);
3070     gtk_widget_show_all(win);
3071     g_free(value);
3072 }
3073
3074 static guint
3075 add_protocol_prefs_menu (pref_t *pref, gpointer data)
3076 {
3077     GtkWidget *menu_preferences;
3078     GtkWidget *menu_item, *menu_sub_item, *sub_menu;
3079     GSList *group = NULL;
3080     module_t *module = data;
3081     const enum_val_t *enum_valp;
3082     gchar *label = NULL;
3083
3084     switch (pref->type) {
3085     case PREF_UINT:
3086         switch (pref->info.base) {
3087         case 8:
3088             label = g_strdup_printf ("%s: %o", pref->title, *pref->varp.uint);
3089             break;
3090         case 10:
3091             label = g_strdup_printf ("%s: %u", pref->title, *pref->varp.uint);
3092             break;
3093         case 16:
3094             label = g_strdup_printf ("%s: %x", pref->title, *pref->varp.uint);
3095             break;
3096         default:
3097             g_assert_not_reached();
3098             break;
3099         }
3100         menu_item = gtk_menu_item_new_with_label(label);
3101         g_object_set_data (G_OBJECT(menu_item), "module", module);
3102         g_signal_connect(menu_item, "activate", G_CALLBACK(menu_prefs_edit_dlg), pref);
3103         g_free (label);
3104         break;
3105     case PREF_BOOL:
3106         menu_item = gtk_check_menu_item_new_with_label(pref->title);
3107         gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(menu_item), *pref->varp.boolp);
3108         g_object_set_data (G_OBJECT(menu_item), "module", module);
3109         g_signal_connect(menu_item, "activate", G_CALLBACK(menu_prefs_toggle_bool), pref->varp.boolp);
3110         break;
3111     case PREF_ENUM:
3112         menu_item = gtk_menu_item_new_with_label(pref->title);
3113         sub_menu = gtk_menu_new();
3114         gtk_menu_item_set_submenu (GTK_MENU_ITEM(menu_item), sub_menu);
3115         enum_valp = pref->info.enum_info.enumvals;
3116         while (enum_valp->name != NULL) {
3117             menu_sub_item = gtk_radio_menu_item_new_with_label(group, enum_valp->description);
3118             group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (menu_sub_item));
3119             if (enum_valp->value == *pref->varp.enump) {
3120                 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(menu_sub_item), TRUE);
3121             }
3122             g_object_set_data (G_OBJECT(menu_sub_item), "module", module);
3123             g_object_set_data (G_OBJECT(menu_sub_item), "enumval", GINT_TO_POINTER(enum_valp->value));
3124             g_signal_connect(menu_sub_item, "activate", G_CALLBACK(menu_prefs_change_enum), pref->varp.enump);
3125             gtk_menu_shell_append (GTK_MENU_SHELL(sub_menu), menu_sub_item);
3126             gtk_widget_show (menu_sub_item);
3127             enum_valp++;
3128         }
3129         break;
3130     case PREF_STRING:
3131         label = g_strdup_printf ("%s: %s", pref->title, *pref->varp.string);
3132         menu_item = gtk_menu_item_new_with_label(label);
3133         g_object_set_data (G_OBJECT(menu_item), "module", module);
3134         g_signal_connect(menu_item, "activate", G_CALLBACK(menu_prefs_edit_dlg), pref);
3135         g_free (label);
3136         break;
3137     case PREF_RANGE:
3138         label = g_strdup_printf ("%s: %s", pref->title, range_convert_range (*pref->varp.range));
3139         menu_item = gtk_menu_item_new_with_label(label);
3140         g_object_set_data (G_OBJECT(menu_item), "module", module);
3141         g_signal_connect(menu_item, "activate", G_CALLBACK(menu_prefs_edit_dlg), pref);
3142         g_free (label);
3143         break;
3144     case PREF_UAT:
3145         label = g_strdup_printf ("%s...", pref->title);
3146         menu_item = gtk_menu_item_new_with_label(label);
3147         g_signal_connect (menu_item, "activate", G_CALLBACK(uat_window_cb), pref->varp.uat);
3148         g_free (label);
3149         break;
3150     case PREF_STATIC_TEXT:
3151     case PREF_OBSOLETE:
3152     default:
3153         /* Nothing to add */
3154         return 0;
3155     }
3156
3157     menu_preferences = gtk_item_factory_get_widget(tree_view_menu_factory, "/Protocol Preferences");
3158     sub_menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM(menu_preferences));
3159     gtk_menu_shell_append (GTK_MENU_SHELL(sub_menu), menu_item);
3160     gtk_widget_show (menu_item);
3161
3162     return 0;
3163 }
3164
3165 static void
3166 rebuild_protocol_prefs_menu (module_t *prefs, gboolean preferences)
3167 {
3168     GtkWidget *menu_preferences, *menu_item;
3169     GtkWidget *sub_menu;
3170     gchar *label;
3171
3172     menu_preferences = gtk_item_factory_get_widget(tree_view_menu_factory, "/Protocol Preferences");
3173
3174     if (preferences) {
3175         sub_menu = gtk_menu_new();
3176         gtk_menu_item_set_submenu (GTK_MENU_ITEM(menu_preferences), sub_menu);
3177
3178         label = g_strdup_printf ("%s Preferences...", prefs->description);
3179         menu_item = gtk_image_menu_item_new_with_label (label);
3180         gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM(menu_item), 
3181                                        gtk_image_new_from_stock(GTK_STOCK_PREFERENCES, GTK_ICON_SIZE_MENU));
3182         gtk_menu_shell_append (GTK_MENU_SHELL(sub_menu), menu_item);
3183         g_signal_connect_swapped(GTK_OBJECT(menu_item), "activate",
3184                                  G_CALLBACK(properties_cb), (GtkObject *) menu_item);
3185         gtk_widget_show (menu_item);
3186         g_free (label);
3187
3188         menu_item = gtk_menu_item_new();
3189         gtk_menu_shell_append (GTK_MENU_SHELL(sub_menu), menu_item);
3190         gtk_widget_show (menu_item);
3191
3192         prefs_pref_foreach(prefs, add_protocol_prefs_menu, prefs);
3193     } else {
3194         /* No preferences, remove sub menu */
3195         gtk_menu_item_set_submenu (GTK_MENU_ITEM(menu_preferences), NULL);
3196     }
3197
3198 }
3199
3200 void
3201 menus_set_column_align_default (gboolean right_justify)
3202 {
3203     GtkWidget   *submenu, *menu_item_child;
3204     GList       *child_list, *child_list_item;
3205     const gchar *menu_item_name;
3206     size_t       menu_item_len;
3207     
3208     /* get the submenu container item */
3209     submenu = packet_list_heading_factory->widget;
3210
3211     /* find the corresponding menu items to update */
3212     child_list = gtk_container_get_children(GTK_CONTAINER(submenu));
3213     child_list_item = child_list;
3214     while(child_list_item) {
3215         menu_item_child = (GTK_BIN(child_list_item->data))->child;
3216         if (menu_item_child != NULL) {
3217             menu_item_name = gtk_label_get_text(GTK_LABEL(menu_item_child));
3218             menu_item_len = strlen (menu_item_name);
3219             if(strncmp(menu_item_name, "Align Left", 10) == 0) {
3220                 if (!right_justify && menu_item_len == 10) {
3221                     gtk_label_set_text(GTK_LABEL(menu_item_child), "Align Left\t(default)");
3222                 } else if (right_justify && menu_item_len > 10) {
3223                     gtk_label_set_text(GTK_LABEL(menu_item_child), "Align Left");
3224                 }
3225             } else if (strncmp (menu_item_name, "Align Right", 11) == 0) {
3226                 if (right_justify && menu_item_len == 11) {
3227                     gtk_label_set_text(GTK_LABEL(menu_item_child), "Align Right\t(default)");
3228                 } else if (!right_justify && menu_item_len > 11) {
3229                     gtk_label_set_text(GTK_LABEL(menu_item_child), "Align Right");
3230                 }
3231             }
3232         }
3233         child_list_item = g_list_next(child_list_item);
3234     }
3235     g_list_free(child_list);
3236 }
3237
3238 void
3239 set_menus_for_selected_tree_row(capture_file *cf)
3240 {
3241     gboolean properties;
3242     gint id;
3243
3244     if (cf->finfo_selected != NULL) {
3245         header_field_info *hfinfo = cf->finfo_selected->hfinfo;
3246         const char *abbrev;
3247         char *prev_abbrev;
3248
3249         if (hfinfo->parent == -1) {
3250             abbrev = hfinfo->abbrev;
3251             id = (hfinfo->type == FT_PROTOCOL) ? proto_get_id((protocol_t *)hfinfo->strings) : -1;
3252         } else {
3253             abbrev = proto_registrar_get_abbrev(hfinfo->parent);
3254             id = hfinfo->parent;
3255         }
3256         properties = prefs_is_registered_protocol(abbrev);
3257
3258         set_menu_sensitivity(main_menu_factory,
3259                              "/File/Export/Selected Packet Bytes...", TRUE);
3260         set_menu_sensitivity(main_menu_factory,
3261                              "/Go/Go to Corresponding Packet", hfinfo->type == FT_FRAMENUM);
3262         set_menu_sensitivity(tree_view_menu_factory,
3263                              "/Go to Corresponding Packet", hfinfo->type == FT_FRAMENUM);
3264         set_menu_sensitivity(main_menu_factory, "/Edit/Copy/Description",
3265                              proto_can_match_selected(cf->finfo_selected, cf->edt));
3266         set_menu_sensitivity(main_menu_factory, "/Edit/Copy/Fieldname",
3267                              proto_can_match_selected(cf->finfo_selected, cf->edt));
3268         set_menu_sensitivity(main_menu_factory, "/Edit/Copy/Value",
3269                              proto_can_match_selected(cf->finfo_selected, cf->edt));
3270         set_menu_sensitivity(main_menu_factory, "/Edit/Copy/As Filter",
3271                              proto_can_match_selected(cf->finfo_selected, cf->edt));
3272         set_menu_sensitivity(tree_view_menu_factory, "/Copy",
3273                              TRUE);
3274         set_menu_sensitivity(tree_view_menu_factory, "/Copy/As Filter",
3275                              proto_can_match_selected(cf->finfo_selected, cf->edt));
3276         set_menu_sensitivity(main_menu_factory, "/Analyze/Apply as Column",
3277                              hfinfo->type != FT_NONE);
3278         set_menu_sensitivity(main_menu_factory, "/Analyze/Apply as Filter",
3279                              proto_can_match_selected(cf->finfo_selected, cf->edt));
3280         set_menu_sensitivity(tree_view_menu_factory, "/Apply as Column",
3281                              hfinfo->type != FT_NONE);
3282         set_menu_sensitivity(tree_view_menu_factory, "/Apply as Filter",
3283                              proto_can_match_selected(cf->finfo_selected, cf->edt));
3284         set_menu_sensitivity(main_menu_factory, "/Analyze/Prepare a Filter",
3285                              proto_can_match_selected(cf->finfo_selected, cf->edt));
3286         set_menu_sensitivity(tree_view_menu_factory, "/Prepare a Filter",
3287                              proto_can_match_selected(cf->finfo_selected, cf->edt));
3288         set_menu_sensitivity(tree_view_menu_factory, "/Colorize with Filter",
3289                              proto_can_match_selected(cf->finfo_selected, cf->edt));
3290         set_menu_sensitivity(tree_view_menu_factory, "/Protocol Preferences",
3291                              properties);
3292         set_menu_sensitivity(tree_view_menu_factory, "/Disable Protocol...",
3293                              (id == -1) ? FALSE : proto_can_toggle_protocol(id));
3294         set_menu_sensitivity(main_menu_factory, "/View/Expand Subtrees", cf->finfo_selected->tree_type != -1);
3295         set_menu_sensitivity(tree_view_menu_factory, "/Expand Subtrees", cf->finfo_selected->tree_type != -1);
3296         set_menu_sensitivity(tree_view_menu_factory, "/Wiki Protocol Page",
3297                              TRUE);
3298         set_menu_sensitivity(tree_view_menu_factory, "/Filter Field Reference",
3299                              TRUE);
3300         
3301         prev_abbrev = g_object_get_data(G_OBJECT(tree_view_menu_factory), "menu_abbrev");
3302         if (!prev_abbrev || (strcmp (prev_abbrev, abbrev) != 0)) {
3303             /* No previous protocol or protocol changed - update Protocol Preferences menu */
3304             module_t *prefs = prefs_find_module(abbrev);
3305             rebuild_protocol_prefs_menu (prefs, properties);
3306
3307             g_object_set_data(G_OBJECT(tree_view_menu_factory), "menu_abbrev", g_strdup(abbrev));
3308             g_free (prev_abbrev);
3309         }
3310     } else {
3311         set_menu_sensitivity(main_menu_factory,
3312                              "/File/Export/Selected Packet Bytes...", FALSE);
3313         set_menu_sensitivity(main_menu_factory,
3314                              "/Go/Go to Corresponding Packet", FALSE);
3315         set_menu_sensitivity(tree_view_menu_factory,
3316                              "/Go to Corresponding Packet", FALSE);
3317         set_menu_sensitivity(main_menu_factory, "/Edit/Copy/Description", FALSE);
3318         set_menu_sensitivity(main_menu_factory, "/Edit/Copy/Fieldname", FALSE);
3319         set_menu_sensitivity(main_menu_factory, "/Edit/Copy/Value", FALSE);
3320         set_menu_sensitivity(main_menu_factory, "/Edit/Copy/As Filter", FALSE);
3321         set_menu_sensitivity(tree_view_menu_factory, "/Copy", FALSE);
3322         set_menu_sensitivity(main_menu_factory, "/Analyze/Apply as Column", FALSE);
3323         set_menu_sensitivity(tree_view_menu_factory, "/Apply as Column", FALSE);
3324         set_menu_sensitivity(main_menu_factory, "/Analyze/Apply as Filter", FALSE);
3325         set_menu_sensitivity(tree_view_menu_factory, "/Apply as Filter", FALSE);
3326         set_menu_sensitivity(main_menu_factory, "/Analyze/Prepare a Filter", FALSE);
3327         set_menu_sensitivity(tree_view_menu_factory, "/Prepare a Filter", FALSE);
3328         set_menu_sensitivity(tree_view_menu_factory, "/Colorize with Filter", FALSE);
3329         set_menu_sensitivity(tree_view_menu_factory, "/Protocol Preferences",
3330                              FALSE);
3331         set_menu_sensitivity(tree_view_menu_factory, "/Disable Protocol...", FALSE);
3332         set_menu_sensitivity(main_menu_factory, "/View/Expand Subtrees", FALSE);
3333         set_menu_sensitivity(tree_view_menu_factory, "/Expand Subtrees", FALSE);
3334         set_menu_sensitivity(tree_view_menu_factory, "/Wiki Protocol Page",
3335                              FALSE);
3336         set_menu_sensitivity(tree_view_menu_factory, "/Filter Field Reference",
3337                              FALSE);
3338     }
3339
3340     walk_menu_tree_for_selected_tree_row(tap_menu_tree_root, cf->finfo_selected);
3341 }
3342
3343 void set_menus_for_packet_history(gboolean back_history, gboolean forward_history) {
3344
3345     set_menu_sensitivity(main_menu_factory, "/Go/Back", back_history);
3346     set_menu_sensitivity(main_menu_factory, "/Go/Forward", forward_history);
3347
3348     set_toolbar_for_packet_history(back_history, forward_history);
3349 }
3350
3351
3352 void set_menus_for_file_set(gboolean file_set, gboolean previous_file, gboolean next_file) {
3353
3354     set_menu_sensitivity(main_menu_factory, "/File/File Set/List Files", file_set);
3355     set_menu_sensitivity(main_menu_factory, "/File/File Set/Previous File", previous_file);
3356     set_menu_sensitivity(main_menu_factory, "/File/File Set/Next File", next_file);
3357 }
3358
3359 /*
3360  * Editor modelines
3361  *
3362  * Local Variables:
3363  * c-basic-offset: 4
3364  * tab-width: 8
3365  * indent-tabs-mode: nil
3366  * End:
3367  *
3368  * ex: set shiftwidth=4 tabstop=8 expandtab
3369  * :indentSize=4:tabSize=8:noTabs=true:
3370  */
3371