Added "No Sorting" and Align menu items to the old packet list
[obnox/wireshark/wip.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 #else
815     {"/Mark Packet (toggle)", NULL, GTK_MENU_FUNC(packet_list_mark_frame_cb), 0, NULL, NULL,},
816 #endif /* NEW_PACKET_LIST */
817     {"/Set Time Reference (toggle)", NULL, GTK_MENU_FUNC(reftime_frame_cb), REFTIME_TOGGLE, "<StockItem>", WIRESHARK_STOCK_TIME,},
818
819     {"/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
820
821     {"/Apply as Filter", NULL, NULL, 0, "<Branch>", NULL,},
822     {"/Apply as Filter/_Selected", NULL, GTK_MENU_FUNC(match_selected_plist_cb),
823                        MATCH_SELECTED_REPLACE|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
824     {"/Apply as Filter/_Not Selected", NULL, GTK_MENU_FUNC(match_selected_plist_cb),
825                        MATCH_SELECTED_NOT|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
826     {"/Apply as Filter/... _and Selected", NULL, GTK_MENU_FUNC(match_selected_plist_cb),
827                        MATCH_SELECTED_AND|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
828     {"/Apply as Filter/... _or Selected", NULL, GTK_MENU_FUNC(match_selected_plist_cb),
829                        MATCH_SELECTED_OR|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
830     {"/Apply as Filter/... a_nd not Selected", NULL, GTK_MENU_FUNC(match_selected_plist_cb),
831                        MATCH_SELECTED_AND_NOT|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
832     {"/Apply as Filter/... o_r not Selected", NULL, GTK_MENU_FUNC(match_selected_plist_cb),
833                        MATCH_SELECTED_OR_NOT|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
834     {"/Prepare a Filter", NULL, NULL, 0, "<Branch>", NULL,},
835     {"/Prepare a Filter/_Selected", NULL, GTK_MENU_FUNC(match_selected_plist_cb),
836                        MATCH_SELECTED_REPLACE, NULL, NULL,},
837     {"/Prepare a Filter/_Not Selected", NULL, GTK_MENU_FUNC(match_selected_plist_cb),
838                        MATCH_SELECTED_NOT, NULL, NULL,},
839     {"/Prepare a Filter/... _and Selected", NULL, GTK_MENU_FUNC(match_selected_plist_cb),
840                        MATCH_SELECTED_AND, NULL, NULL,},
841     {"/Prepare a Filter/... _or Selected", NULL, GTK_MENU_FUNC(match_selected_plist_cb),
842                        MATCH_SELECTED_OR, NULL, NULL,},
843     {"/Prepare a Filter/... a_nd not Selected", NULL, GTK_MENU_FUNC(match_selected_plist_cb),
844                        MATCH_SELECTED_AND_NOT, NULL, NULL,},
845     {"/Prepare a Filter/... o_r not Selected", NULL, GTK_MENU_FUNC(match_selected_plist_cb),
846                        MATCH_SELECTED_OR_NOT, NULL, NULL,},
847     {"/Conversation Filter", NULL, NULL, 0, "<Branch>",NULL,},
848     {"/Conversation Filter/Ethernet", NULL, GTK_MENU_FUNC(conversation_cb),
849                        CONV_ETHER, NULL, NULL,},
850     {"/Conversation Filter/IP", NULL, GTK_MENU_FUNC(conversation_cb),
851                        CONV_IP, NULL, NULL,},
852     {"/Conversation Filter/TCP", NULL, GTK_MENU_FUNC(conversation_cb),
853                        CONV_TCP, NULL, NULL,},
854     {"/Conversation Filter/UDP", NULL, GTK_MENU_FUNC(conversation_cb),
855                        CONV_UDP, NULL, NULL,},
856     {"/Conversation Filter/PN-CBA Server", NULL, GTK_MENU_FUNC(conversation_cb),
857                        CONV_CBA, NULL, NULL,},
858
859     {"/Colorize Conversation", NULL, NULL, 0, "<Branch>",NULL,},
860     {"/Colorize Conversation/Ethernet", NULL, NULL, 0, "<Branch>",NULL,},
861     {"/Colorize Conversation/Ethernet/Color 1", NULL,
862                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_ETHER+1*256, "<StockItem>", WIRESHARK_STOCK_COLOR1,},
863     {"/Colorize Conversation/Ethernet/Color 2", NULL,
864                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_ETHER+2*256, "<StockItem>", WIRESHARK_STOCK_COLOR2,},
865     {"/Colorize Conversation/Ethernet/Color 3", NULL,
866                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_ETHER+3*256, "<StockItem>", WIRESHARK_STOCK_COLOR3,},
867     {"/Colorize Conversation/Ethernet/Color 4", NULL,
868                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_ETHER+4*256, "<StockItem>", WIRESHARK_STOCK_COLOR4,},
869     {"/Colorize Conversation/Ethernet/Color 5", NULL,
870                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_ETHER+5*256, "<StockItem>", WIRESHARK_STOCK_COLOR5,},
871     {"/Colorize Conversation/Ethernet/Color 6", NULL,
872                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_ETHER+6*256, "<StockItem>", WIRESHARK_STOCK_COLOR6,},
873     {"/Colorize Conversation/Ethernet/Color 7", NULL,
874                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_ETHER+7*256, "<StockItem>", WIRESHARK_STOCK_COLOR7,},
875     {"/Colorize Conversation/Ethernet/Color 8", NULL,
876                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_ETHER+8*256, "<StockItem>", WIRESHARK_STOCK_COLOR8,},
877     {"/Colorize Conversation/Ethernet/Color 9", NULL,
878                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_ETHER+9*256, "<StockItem>", WIRESHARK_STOCK_COLOR9,},
879     {"/Colorize Conversation/Ethernet/Color 10", NULL,
880                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_ETHER+10*256, "<StockItem>", WIRESHARK_STOCK_COLOR0,},
881     {"/Colorize Conversation/Ethernet/<separator>", NULL,
882                        NULL, 0, "<Separator>",NULL,},
883     {"/Colorize Conversation/Ethernet/New Coloring Rule...", NULL,
884                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_ETHER, "<StockItem>", GTK_STOCK_SELECT_COLOR,},
885     {"/Colorize Conversation/IP", NULL, NULL, 0, "<Branch>",NULL,},
886     {"/Colorize Conversation/IP/Color 1", NULL,
887                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_IP+1*256, "<StockItem>", WIRESHARK_STOCK_COLOR1,},
888     {"/Colorize Conversation/IP/Color 2", NULL,
889                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_IP+2*256, "<StockItem>", WIRESHARK_STOCK_COLOR2,},
890     {"/Colorize Conversation/IP/Color 3", NULL,
891                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_IP+3*256, "<StockItem>", WIRESHARK_STOCK_COLOR3,},
892     {"/Colorize Conversation/IP/Color 4", NULL,
893                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_IP+4*256, "<StockItem>", WIRESHARK_STOCK_COLOR4,},
894     {"/Colorize Conversation/IP/Color 5", NULL,
895                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_IP+5*256, "<StockItem>", WIRESHARK_STOCK_COLOR5,},
896     {"/Colorize Conversation/IP/Color 6", NULL,
897                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_IP+6*256, "<StockItem>", WIRESHARK_STOCK_COLOR6,},
898     {"/Colorize Conversation/IP/Color 7", NULL,
899                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_IP+7*256, "<StockItem>", WIRESHARK_STOCK_COLOR7,},
900     {"/Colorize Conversation/IP/Color 8", NULL,
901                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_IP+8*256, "<StockItem>", WIRESHARK_STOCK_COLOR8,},
902     {"/Colorize Conversation/IP/Color 9", NULL,
903                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_IP+9*256, "<StockItem>", WIRESHARK_STOCK_COLOR9,},
904     {"/Colorize Conversation/IP/Color 10", NULL,
905                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_IP+10*256, "<StockItem>", WIRESHARK_STOCK_COLOR0,},
906     {"/Colorize Conversation/IP/<separator>", NULL,
907                        NULL, 0, "<Separator>",NULL,},
908     {"/Colorize Conversation/IP/New Coloring Rule...", NULL,
909                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_IP, "<StockItem>", GTK_STOCK_SELECT_COLOR,},
910     {"/Colorize Conversation/TCP", NULL, NULL, 0, "<Branch>",NULL,},
911     {"/Colorize Conversation/TCP/Color 1", NULL,
912                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_TCP+1*256, "<StockItem>", WIRESHARK_STOCK_COLOR1,},
913     {"/Colorize Conversation/TCP/Color 2", NULL,
914                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_TCP+2*256, "<StockItem>", WIRESHARK_STOCK_COLOR2,},
915     {"/Colorize Conversation/TCP/Color 3", NULL,
916                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_TCP+3*256, "<StockItem>", WIRESHARK_STOCK_COLOR3,},
917     {"/Colorize Conversation/TCP/Color 4", NULL,
918                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_TCP+4*256, "<StockItem>", WIRESHARK_STOCK_COLOR4,},
919     {"/Colorize Conversation/TCP/Color 5", NULL,
920                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_TCP+5*256, "<StockItem>", WIRESHARK_STOCK_COLOR5,},
921     {"/Colorize Conversation/TCP/Color 6", NULL,
922                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_TCP+6*256, "<StockItem>", WIRESHARK_STOCK_COLOR6,},
923     {"/Colorize Conversation/TCP/Color 7", NULL,
924                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_TCP+7*256, "<StockItem>", WIRESHARK_STOCK_COLOR7,},
925     {"/Colorize Conversation/TCP/Color 8", NULL,
926                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_TCP+8*256, "<StockItem>", WIRESHARK_STOCK_COLOR8,},
927     {"/Colorize Conversation/TCP/Color 9", NULL,
928                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_TCP+9*256, "<StockItem>", WIRESHARK_STOCK_COLOR9,},
929     {"/Colorize Conversation/TCP/Color 10", NULL,
930                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_TCP+10*256, "<StockItem>", WIRESHARK_STOCK_COLOR0,},
931     {"/Colorize Conversation/TCP/<separator>", NULL,
932                        NULL, 0, "<Separator>",NULL,},
933     {"/Colorize Conversation/TCP/New Coloring Rule...", NULL,
934                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_TCP, "<StockItem>", GTK_STOCK_SELECT_COLOR,},
935     {"/Colorize Conversation/UDP", NULL, NULL, 0, "<Branch>",NULL,},
936     {"/Colorize Conversation/UDP/Color 1", NULL,
937                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_UDP+1*256, "<StockItem>", WIRESHARK_STOCK_COLOR1,},
938     {"/Colorize Conversation/UDP/Color 2", NULL,
939                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_UDP+2*256, "<StockItem>", WIRESHARK_STOCK_COLOR2,},
940     {"/Colorize Conversation/UDP/Color 3", NULL,
941                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_UDP+3*256, "<StockItem>", WIRESHARK_STOCK_COLOR3,},
942     {"/Colorize Conversation/UDP/Color 4", NULL,
943                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_UDP+4*256, "<StockItem>", WIRESHARK_STOCK_COLOR4,},
944     {"/Colorize Conversation/UDP/Color 5", NULL,
945                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_UDP+5*256, "<StockItem>", WIRESHARK_STOCK_COLOR5,},
946     {"/Colorize Conversation/UDP/Color 6", NULL,
947                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_UDP+6*256, "<StockItem>", WIRESHARK_STOCK_COLOR6,},
948     {"/Colorize Conversation/UDP/Color 7", NULL,
949                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_UDP+7*256, "<StockItem>", WIRESHARK_STOCK_COLOR7,},
950     {"/Colorize Conversation/UDP/Color 8", NULL,
951                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_UDP+8*256, "<StockItem>", WIRESHARK_STOCK_COLOR8,},
952     {"/Colorize Conversation/UDP/Color 9", NULL,
953                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_UDP+9*256, "<StockItem>", WIRESHARK_STOCK_COLOR9,},
954     {"/Colorize Conversation/UDP/Color 10", NULL,
955                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_UDP+10*256, "<StockItem>", WIRESHARK_STOCK_COLOR0,},
956     {"/Colorize Conversation/UDP/<separator>", NULL,
957                        NULL, 0, "<Separator>",NULL,},
958     {"/Colorize Conversation/UDP/New Coloring Rule...", NULL,
959                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_UDP, "<StockItem>", GTK_STOCK_SELECT_COLOR,},
960     {"/Colorize Conversation/PN-CBA Server", NULL, NULL, 0, "<Branch>",NULL,},
961     {"/Colorize Conversation/PN-CBA Server/Color 1", NULL,
962                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_CBA+1*256, "<StockItem>", WIRESHARK_STOCK_COLOR1,},
963     {"/Colorize Conversation/PN-CBA Server/Color 2", NULL,
964                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_CBA+2*256, "<StockItem>", WIRESHARK_STOCK_COLOR2,},
965     {"/Colorize Conversation/PN-CBA Server/Color 3", NULL,
966                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_CBA+3*256, "<StockItem>", WIRESHARK_STOCK_COLOR3,},
967     {"/Colorize Conversation/PN-CBA Server/Color 4", NULL,
968                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_CBA+4*256, "<StockItem>", WIRESHARK_STOCK_COLOR4,},
969     {"/Colorize Conversation/PN-CBA Server/Color 5", NULL,
970                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_CBA+5*256, "<StockItem>", WIRESHARK_STOCK_COLOR5,},
971     {"/Colorize Conversation/PN-CBA Server/Color 6", NULL,
972                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_CBA+6*256, "<StockItem>", WIRESHARK_STOCK_COLOR6,},
973     {"/Colorize Conversation/PN-CBA Server/Color 7", NULL,
974                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_CBA+7*256, "<StockItem>", WIRESHARK_STOCK_COLOR7,},
975     {"/Colorize Conversation/PN-CBA Server/Color 8", NULL,
976                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_CBA+8*256, "<StockItem>", WIRESHARK_STOCK_COLOR8,},
977     {"/Colorize Conversation/PN-CBA Server/Color 9", NULL,
978                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_CBA+9*256, "<StockItem>", WIRESHARK_STOCK_COLOR9,},
979     {"/Colorize Conversation/PN-CBA Server/Color 10", NULL,
980                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_CBA+10*256, "<StockItem>", WIRESHARK_STOCK_COLOR0,},
981     {"/Colorize Conversation/PN-CBA Server/<separator>", NULL,
982                        NULL, 0, "<Separator>",NULL,},
983     {"/Colorize Conversation/PN-CBA Server/New Coloring Rule...", NULL,
984                        GTK_MENU_FUNC(colorize_conversation_cb), CONV_CBA, "<StockItem>", GTK_STOCK_SELECT_COLOR,},
985
986     {"/SCTP", NULL, NULL, 0, "<Branch>",NULL,},
987     {"/SCTP/Analyse this Association", NULL, GTK_MENU_FUNC(sctp_analyse_start),
988                        0, NULL,NULL,},
989     {"/SCTP/Prepare Filter for this Association", NULL, (sctp_set_assoc_filter),
990                        0, NULL,NULL,},
991
992     {"/Follow TCP Stream", NULL, (follow_tcp_stream_cb),
993                        0, NULL, NULL,},
994     {"/Follow UDP Stream", NULL, (follow_udp_stream_cb),
995                        0, NULL, NULL,},
996     {"/Follow SSL Stream", NULL, (follow_ssl_stream_cb),
997                        0, NULL, NULL,},
998
999     {"/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
1000     {"/Copy", NULL, NULL, 0, "<Branch>", NULL,},
1001 #ifdef NEW_PACKET_LIST
1002     {"/Copy/Summary (Text)", NULL, GTK_MENU_FUNC(new_packet_list_copy_summary_cb), CS_TEXT, NULL, NULL,},
1003     {"/Copy/Summary (CSV)", NULL, GTK_MENU_FUNC(new_packet_list_copy_summary_cb), CS_CSV, NULL, NULL,},
1004     {"/Copy/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
1005 #else
1006     {"/Copy/Summary (Text)", NULL, GTK_MENU_FUNC(packet_list_copy_summary_cb), CS_TEXT, NULL, NULL,},
1007     {"/Copy/Summary (CSV)", NULL, GTK_MENU_FUNC(packet_list_copy_summary_cb), CS_CSV, NULL, NULL,},
1008     {"/Copy/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
1009 #endif /* NEW_PACKET_LIST */
1010     {"/Copy/As Filter", NULL, GTK_MENU_FUNC(match_selected_plist_cb),
1011                        MATCH_SELECTED_REPLACE|MATCH_SELECTED_COPY_ONLY, NULL, NULL,},
1012     {"/Copy/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
1013     {"/Copy/Bytes (Offset Hex Text)", NULL, GTK_MENU_FUNC(copy_hex_cb), CD_ALLINFO, NULL, NULL,},
1014     {"/Copy/Bytes (Offset Hex)", NULL, GTK_MENU_FUNC(copy_hex_cb), CD_HEXCOLUMNS, NULL, NULL,},
1015     {"/Copy/Bytes (Printable Text Only)", NULL, GTK_MENU_FUNC(copy_hex_cb), CD_TEXTONLY, NULL, NULL,},
1016     {"/Copy/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
1017     {"/Copy/Bytes (Hex Stream)", NULL, GTK_MENU_FUNC(copy_hex_cb), CD_HEX, NULL, NULL,},
1018     {"/Copy/Bytes (Binary Stream)", NULL, GTK_MENU_FUNC(copy_hex_cb), CD_BINARY, NULL, NULL,},
1019
1020     {"/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
1021
1022     {"/Decode As...", NULL, GTK_MENU_FUNC(decode_as_cb), 0, "<StockItem>", WIRESHARK_STOCK_DECODE_AS,},
1023     {"/Print...", NULL, GTK_MENU_FUNC(file_print_selected_cmd_cb), 0, "<StockItem>", GTK_STOCK_PRINT,},
1024     {"/Show Packet in New Window", NULL, GTK_MENU_FUNC(new_window_cb),
1025                        0, NULL, NULL}
1026 };
1027
1028 static GtkItemFactoryEntry tree_view_menu_items[] =
1029 {
1030
1031     {"/Expand Subtrees", NULL, GTK_MENU_FUNC(expand_tree_cb), 0, NULL, NULL,},
1032     {"/Expand All", NULL, GTK_MENU_FUNC(expand_all_cb), 0, NULL, NULL,},
1033     {"/Collapse All", NULL, GTK_MENU_FUNC(collapse_all_cb), 0, NULL, NULL,},
1034
1035     {"/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
1036
1037     {"/Apply as Column", NULL, GTK_MENU_FUNC(apply_as_custom_column_cb), 0, NULL, NULL},
1038
1039     {"/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
1040
1041     {"/Apply as Filter", NULL, NULL, 0, "<Branch>", NULL,},
1042     {"/Apply as Filter/_Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
1043                        MATCH_SELECTED_REPLACE|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
1044     {"/Apply as Filter/_Not Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
1045                        MATCH_SELECTED_NOT|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
1046     {"/Apply as Filter/... _and Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
1047                        MATCH_SELECTED_AND|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
1048     {"/Apply as Filter/... _or Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
1049                        MATCH_SELECTED_OR|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
1050     {"/Apply as Filter/... a_nd not Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
1051                        MATCH_SELECTED_AND_NOT|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
1052     {"/Apply as Filter/... o_r not Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
1053                        MATCH_SELECTED_OR_NOT|MATCH_SELECTED_APPLY_NOW, NULL, NULL,},
1054
1055     {"/Prepare a Filter", NULL, NULL, 0, "<Branch>", NULL,},
1056     {"/Prepare a Filter/_Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
1057                        MATCH_SELECTED_REPLACE, NULL, NULL,},
1058     {"/Prepare a Filter/_Not Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
1059                        MATCH_SELECTED_NOT, NULL, NULL,},
1060     {"/Prepare a Filter/... _and Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
1061                        MATCH_SELECTED_AND, NULL, NULL,},
1062     {"/Prepare a Filter/... _or Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
1063                        MATCH_SELECTED_OR, NULL, NULL,},
1064     {"/Prepare a Filter/... a_nd not Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
1065                        MATCH_SELECTED_AND_NOT, NULL, NULL,},
1066     {"/Prepare a Filter/... o_r not Selected", NULL, GTK_MENU_FUNC(match_selected_ptree_cb),
1067                        MATCH_SELECTED_OR_NOT, NULL, NULL,},
1068
1069     {"/Colorize with Filter", NULL, NULL, 0, "<Branch>", NULL,},
1070     {"/Colorize with Filter/Color 1", NULL, GTK_MENU_FUNC(colorize_selected_ptree_cb), 1, "<StockItem>", WIRESHARK_STOCK_COLOR1,},
1071     {"/Colorize with Filter/Color 2", NULL, GTK_MENU_FUNC(colorize_selected_ptree_cb), 2, "<StockItem>", WIRESHARK_STOCK_COLOR2,},
1072     {"/Colorize with Filter/Color 3", NULL, GTK_MENU_FUNC(colorize_selected_ptree_cb), 3, "<StockItem>", WIRESHARK_STOCK_COLOR3,},
1073     {"/Colorize with Filter/Color 4", NULL, GTK_MENU_FUNC(colorize_selected_ptree_cb), 4, "<StockItem>", WIRESHARK_STOCK_COLOR4,},
1074     {"/Colorize with Filter/Color 5", NULL, GTK_MENU_FUNC(colorize_selected_ptree_cb), 5, "<StockItem>", WIRESHARK_STOCK_COLOR5,},
1075     {"/Colorize with Filter/Color 6", NULL, GTK_MENU_FUNC(colorize_selected_ptree_cb), 6, "<StockItem>", WIRESHARK_STOCK_COLOR6,},
1076     {"/Colorize with Filter/Color 7", NULL, GTK_MENU_FUNC(colorize_selected_ptree_cb), 7, "<StockItem>", WIRESHARK_STOCK_COLOR7,},
1077     {"/Colorize with Filter/Color 8", NULL, GTK_MENU_FUNC(colorize_selected_ptree_cb), 8, "<StockItem>", WIRESHARK_STOCK_COLOR8,},
1078     {"/Colorize with Filter/Color 9", NULL, GTK_MENU_FUNC(colorize_selected_ptree_cb), 9, "<StockItem>", WIRESHARK_STOCK_COLOR9,},
1079     {"/Colorize with Filter/Color 10", NULL, GTK_MENU_FUNC(colorize_selected_ptree_cb), 10, "<StockItem>", WIRESHARK_STOCK_COLOR0,},
1080     {"/Colorize with Filter/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
1081     {"/Colorize with Filter/New Coloring Rule...", NULL, GTK_MENU_FUNC(colorize_selected_ptree_cb), 0, "<StockItem>", GTK_STOCK_SELECT_COLOR,},
1082
1083     {"/Follow TCP Stream", NULL, GTK_MENU_FUNC(follow_tcp_stream_cb),
1084                        0, NULL, NULL,},
1085     {"/Follow UDP Stream", NULL, GTK_MENU_FUNC(follow_udp_stream_cb),
1086                        0, NULL, NULL,},
1087     {"/Follow SSL Stream", NULL, GTK_MENU_FUNC(follow_ssl_stream_cb),
1088                        0, NULL, NULL,},
1089
1090     {"/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
1091
1092     {"/Copy", NULL, NULL, 0, "<Branch>", NULL,},
1093     {"/Copy/Description", NULL, GTK_MENU_FUNC(copy_selected_plist_cb), COPY_SELECTED_DESCRIPTION, NULL, NULL,},
1094     {"/Copy/Fieldname", NULL, GTK_MENU_FUNC(copy_selected_plist_cb), COPY_SELECTED_FIELDNAME, NULL, NULL,},
1095     {"/Copy/Value", NULL, GTK_MENU_FUNC(copy_selected_plist_cb), COPY_SELECTED_VALUE, NULL, NULL,},
1096     {"/Copy/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
1097     {"/Copy/As Filter", NULL, GTK_MENU_FUNC(match_selected_ptree_cb), MATCH_SELECTED_REPLACE|MATCH_SELECTED_COPY_ONLY, NULL, NULL,},
1098     {"/Copy/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
1099     {"/Copy/Bytes (Offset Hex Text)", NULL, GTK_MENU_FUNC(copy_hex_cb), CD_ALLINFO | CD_FLAGS_SELECTEDONLY, NULL, NULL,},
1100     {"/Copy/Bytes (Offset Hex)", NULL, GTK_MENU_FUNC(copy_hex_cb), CD_HEXCOLUMNS | CD_FLAGS_SELECTEDONLY, NULL, NULL,},
1101     {"/Copy/Bytes (Printable Text Only)", NULL, GTK_MENU_FUNC(copy_hex_cb), CD_TEXTONLY | CD_FLAGS_SELECTEDONLY, NULL, NULL,},
1102     {"/Copy/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
1103     {"/Copy/Bytes (Hex Stream)", NULL, GTK_MENU_FUNC(copy_hex_cb), CD_HEX | CD_FLAGS_SELECTEDONLY, NULL, NULL,},
1104     {"/Copy/Bytes (Binary Stream)", NULL, GTK_MENU_FUNC(copy_hex_cb), CD_BINARY | CD_FLAGS_SELECTEDONLY, NULL, NULL,},
1105
1106     {"/Export Selected Packet Bytes...", NULL, GTK_MENU_FUNC(savehex_cb),
1107                        0, NULL, NULL,},
1108
1109     {"/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
1110
1111     {"/Wiki Protocol Page", NULL, GTK_MENU_FUNC(selected_ptree_info_cb),
1112                        0, "<StockItem>", WIRESHARK_STOCK_WIKI,},
1113     {"/Filter Field Reference", NULL, GTK_MENU_FUNC(selected_ptree_ref_cb),
1114                        0, "<StockItem>", WIRESHARK_STOCK_INTERNET,},
1115     {"/Protocol Preferences", NULL, NULL, 0, NULL, NULL,},
1116     {"/<separator>", NULL, NULL, 0, "<Separator>", NULL,},
1117     {"/Decode As...", NULL, GTK_MENU_FUNC(decode_as_cb), 0, "<StockItem>", WIRESHARK_STOCK_DECODE_AS,},
1118     {"/Disable Protocol...", NULL, GTK_MENU_FUNC(proto_disable_cb), 0, "<StockItem>", WIRESHARK_STOCK_CHECKBOX,},
1119     {"/_Resolve Name", NULL, GTK_MENU_FUNC(resolve_name_cb), 0, NULL, NULL,},
1120     {"/_Go to Corresponding Packet", NULL, GTK_MENU_FUNC(goto_framenum_cb), 0, NULL, NULL,}
1121 };
1122
1123 static GtkItemFactoryEntry bytes_menu_items[] =
1124 {
1125     {"/Hex View", NULL, GTK_MENU_FUNC(select_bytes_view), BYTES_HEX, "<RadioItem>", NULL,},
1126     {"/Bits View", NULL, GTK_MENU_FUNC(select_bytes_view), BYTES_BITS, "/Hex View", NULL,}
1127 };
1128
1129
1130 static int initialize = TRUE;
1131 static GtkItemFactory *main_menu_factory = NULL;
1132 static GtkItemFactory *packet_list_heading_factory = NULL;
1133 static GtkItemFactory *packet_list_menu_factory = NULL;
1134 static GtkItemFactory *tree_view_menu_factory = NULL;
1135 static GtkItemFactory *bytes_menu_factory = NULL;
1136
1137 static GSList *popup_menu_list = NULL;
1138
1139 static GtkAccelGroup *grp;
1140
1141 GtkWidget *
1142 main_menu_new(GtkAccelGroup ** table) {
1143     GtkWidget *menubar;
1144 #ifdef HAVE_IGE_MAC_INTEGRATION
1145     GtkWidget *quit_item, *about_item, *preferences_item;
1146     IgeMacMenuGroup *group;
1147 #endif
1148
1149     grp = gtk_accel_group_new();
1150
1151     if (initialize)
1152         menus_init();
1153
1154     menubar = main_menu_factory->widget;
1155
1156 #ifdef HAVE_IGE_MAC_INTEGRATION
1157     if(prefs.gui_macosx_style) {
1158         ige_mac_menu_set_menu_bar(GTK_MENU_SHELL(menubar));
1159         ige_mac_menu_set_global_key_handler_enabled(TRUE);
1160
1161         /* Create menu items to populate the application menu with.  We have to
1162          * do this because we are still using the old GtkItemFactory API for
1163          * the main menu. */
1164         group = ige_mac_menu_add_app_menu_group();
1165         about_item = gtk_menu_item_new_with_label("About");
1166         g_signal_connect(about_item, "activate", G_CALLBACK(about_wireshark_cb),
1167                          NULL);
1168         ige_mac_menu_add_app_menu_item(group, GTK_MENU_ITEM(about_item), NULL);
1169
1170         group = ige_mac_menu_add_app_menu_group();
1171         preferences_item = gtk_menu_item_new_with_label("Preferences");
1172         g_signal_connect(preferences_item, "activate", G_CALLBACK(prefs_cb),
1173                          NULL);
1174         ige_mac_menu_add_app_menu_item(group, GTK_MENU_ITEM(preferences_item),
1175                                        NULL);
1176     }
1177
1178     /* The quit item in the application menu shows up whenever ige mac
1179      * integration is enabled, even if the OS X UI style in Wireshark isn't
1180      * turned on. */
1181     quit_item = gtk_menu_item_new_with_label("Quit");
1182     g_signal_connect(quit_item, "activate", G_CALLBACK(file_quit_cmd_cb), NULL);
1183     ige_mac_menu_set_quit_menu_item(GTK_MENU_ITEM(quit_item));
1184 #endif
1185
1186     if (table)
1187         *table = grp;
1188
1189     return menubar;
1190 }
1191
1192
1193 void menu_dissector_filter_cb(  GtkWidget *widget _U_,
1194                                 gpointer callback_data,
1195                                 guint callback_action _U_)
1196 {
1197     dissector_filter_t      *filter_entry = callback_data;
1198     GtkWidget               *filter_te;
1199     const char              *buf;    
1200
1201
1202     filter_te = g_object_get_data(G_OBJECT(popup_menu_object), E_DFILTER_TE_KEY);
1203
1204     /* XXX - this gets the packet_info of the last dissected packet, */
1205     /* which is not necessarily the last selected packet */
1206     /* e.g. "Update list of packets in real time" won't work correct */
1207     buf = filter_entry->build_filter_string(&cfile.edt->pi);
1208
1209     gtk_entry_set_text(GTK_ENTRY(filter_te), buf);
1210
1211     /* Run the display filter so it goes in effect - even if it's the
1212        same as the previous display filter. */
1213     main_filter_packets(&cfile, buf, TRUE);
1214
1215     g_free( (void *) buf);
1216 }
1217
1218 gboolean menu_dissector_filter_spe_cb(frame_data *fd _U_, epan_dissect_t *edt, gpointer callback_data) {
1219     dissector_filter_t *filter_entry = callback_data;
1220
1221     /* XXX - this gets the packet_info of the last dissected packet, */
1222     /* which is not necessarily the last selected packet */
1223     /* e.g. "Update list of packets in real time" won't work correct */
1224     return (edt != NULL) ? filter_entry->is_filter_valid(&edt->pi) : FALSE;
1225 }
1226
1227 void menu_dissector_filter(void) {
1228     GList *list_entry = dissector_filter_list;
1229     dissector_filter_t *filter_entry;
1230
1231     while(list_entry != NULL) {
1232         filter_entry = list_entry->data;
1233
1234         register_stat_menu_item(filter_entry->name, REGISTER_ANALYZE_GROUP_CONVERSATION_FILTER,
1235             menu_dissector_filter_cb,
1236             menu_dissector_filter_spe_cb,
1237             NULL /* selected_tree_row_enabled */,
1238             filter_entry);
1239
1240         list_entry = g_list_next(list_entry);
1241     }
1242 }
1243
1244
1245 static void
1246 menus_init(void) {
1247     if (initialize) {
1248         initialize = FALSE;
1249
1250     popup_menu_object = gtk_menu_new();
1251
1252     /* packet list heading pop-up menu */
1253     packet_list_heading_factory = gtk_item_factory_new(GTK_TYPE_MENU, "<main>", NULL);
1254     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);
1255     g_object_set_data(G_OBJECT(popup_menu_object), PM_PACKET_LIST_COL_KEY,
1256                     packet_list_heading_factory->widget);
1257     popup_menu_list = g_slist_append((GSList *)popup_menu_list, packet_list_heading_factory);
1258
1259     /* packet list pop-up menu */
1260     packet_list_menu_factory = gtk_item_factory_new(GTK_TYPE_MENU, "<main>", NULL);
1261     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);
1262     g_object_set_data(G_OBJECT(popup_menu_object), PM_PACKET_LIST_KEY,
1263                     packet_list_menu_factory->widget);
1264     popup_menu_list = g_slist_append((GSList *)popup_menu_list, packet_list_menu_factory);
1265
1266     /* packet detail pop-up menu */
1267     tree_view_menu_factory = gtk_item_factory_new(GTK_TYPE_MENU, "<main>", NULL);
1268     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);
1269     g_object_set_data(G_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY,
1270                     tree_view_menu_factory->widget);
1271     popup_menu_list = g_slist_append((GSList *)popup_menu_list, tree_view_menu_factory);
1272
1273     /*
1274      * Hex dump pop-up menu.
1275      * We provide our own empty menu to suppress the default pop-up menu
1276      * for text widgets.
1277      */
1278     bytes_menu_factory = gtk_item_factory_new(GTK_TYPE_MENU, "<main>", NULL);
1279     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);
1280     g_object_set_data(G_OBJECT(popup_menu_object), PM_BYTES_VIEW_KEY,
1281                     bytes_menu_factory->widget);
1282     popup_menu_list = g_slist_append((GSList *)popup_menu_list, bytes_menu_factory);
1283
1284     /* main */
1285     main_menu_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", grp);
1286     gtk_item_factory_create_items_ac(main_menu_factory, nmenu_items, menu_items, NULL, 2);
1287
1288     menu_dissector_filter();
1289     merge_all_tap_menus(tap_menu_tree_root);
1290
1291     /* Initialize enabled/disabled state of menu items */
1292     set_menus_for_capture_file(NULL);
1293 #if 0
1294     /* Un-#if this when we actually implement Cut/Copy/Paste.
1295        Then make sure you enable them when they can be done. */
1296     set_menu_sensitivity(main_menu_factory, "/Edit/Cut", FALSE);
1297     set_menu_sensitivity(main_menu_factory, "/Edit/Copy", FALSE);
1298     set_menu_sensitivity(main_menu_factory, "/Edit/Paste", FALSE);
1299 #endif
1300
1301     set_menus_for_captured_packets(FALSE);
1302     set_menus_for_selected_packet(&cfile);
1303     set_menus_for_selected_tree_row(&cfile);
1304     set_menus_for_capture_in_progress(FALSE);
1305     set_menus_for_file_set(/* dialog */TRUE, /* previous file */ FALSE, /* next_file */ FALSE);
1306
1307     /* init with an empty recent files list */
1308     clear_menu_recent_capture_file_cmd_cb(NULL, NULL);
1309
1310     }
1311 }
1312
1313
1314 static gint tap_menu_item_add_compare(gconstpointer a, gconstpointer b)
1315 {
1316     return strcmp(
1317         ((const menu_item_t *) a)->name,
1318         ((const menu_item_t *) b)->name);
1319 }
1320
1321
1322 /* add a menuitem below the current node */
1323 static GList * tap_menu_item_add(
1324     char *name,
1325     gint group,
1326     const char *stock_id,
1327     GtkItemFactoryCallback callback,
1328     gboolean (*selected_packet_enabled)(frame_data *, epan_dissect_t *, gpointer callback_data),
1329     gboolean (*selected_tree_row_enabled)(field_info *, gpointer callback_data),
1330     gpointer callback_data,
1331     GList *curnode)
1332 {
1333     menu_item_t *curr;
1334     menu_item_t *child;
1335
1336
1337     child = g_malloc(sizeof (menu_item_t));
1338     child->name             = name;
1339     child->group            = group;
1340     child->stock_id         = stock_id;
1341     child->callback         = callback;
1342     child->selected_packet_enabled = selected_packet_enabled;
1343     child->selected_tree_row_enabled = selected_tree_row_enabled;
1344     child->callback_data    = callback_data;
1345     child->enabled          = FALSE;
1346     child->children         = NULL;
1347
1348     /* insert the new child node into the parent */
1349     curr = curnode->data;
1350     curr->children = g_list_insert_sorted(curr->children, child, tap_menu_item_add_compare);
1351
1352     /* return the new node */
1353     /* XXX: improve this */
1354     return g_list_find(curr->children, child);
1355 }
1356
1357 /*
1358  * Add a new menu item for a tap.
1359  * This must be called after we've created the main menu, so it can't
1360  * be called from the routine that registers taps - we have to introduce
1361  * another per-tap registration routine.
1362  *
1363  * "callback" gets called when the menu item is selected; it should do
1364  * the work of creating the tap window.
1365  *
1366  * "selected_packet_enabled" gets called by "set_menus_for_selected_packet()";
1367  * it's passed a Boolean that's TRUE if a packet is selected and FALSE
1368  * otherwise, and should return TRUE if the tap will work now (which
1369  * might depend on whether a packet is selected and, if one is, on the
1370  * packet) and FALSE if not.
1371  *
1372  * "selected_tree_row_enabled" gets called by
1373  * "set_menus_for_selected_tree_row()"; it's passed a Boolean that's TRUE if
1374  * a protocol tree row is selected and FALSE otherwise, and should return
1375  * TRUE if the tap will work now (which might depend on whether a tree row
1376  * is selected and, if one is, on the tree row) and FALSE if not.
1377  */
1378 void
1379 register_stat_menu_item_stock(
1380     const char *name,
1381     register_stat_group_t group,
1382     const char *stock_id,
1383     GtkItemFactoryCallback callback,
1384     gboolean (*selected_packet_enabled)(frame_data *, epan_dissect_t *, gpointer callback_data),
1385     gboolean (*selected_tree_row_enabled)(field_info *, gpointer callback_data),
1386     gpointer callback_data)
1387 {
1388     /*static const char toolspath[] = "/Statistics/";*/
1389     const char *toolspath;
1390     const char *p;
1391     char *menupath;
1392     size_t menupathlen;
1393     menu_item_t *child;
1394     GList *curnode;
1395     GList *childnode;
1396
1397     /*
1398      * The menu path must be relative.
1399      */
1400     g_assert(*name != '/');
1401
1402     switch(group) {
1403     case(REGISTER_STAT_GROUP_GENERIC): toolspath = "/Statistics/"; break;
1404     case(REGISTER_STAT_GROUP_CONVERSATION_LIST): toolspath = "/Statistics/_Conversation List/"; break;
1405     case(REGISTER_STAT_GROUP_ENDPOINT_LIST): toolspath = "/Statistics/_Endpoint List/"; break;
1406     case(REGISTER_STAT_GROUP_RESPONSE_TIME): toolspath = "/Statistics/Service _Response Time/"; break;
1407     case(REGISTER_STAT_GROUP_UNSORTED): toolspath = "/Statistics/"; break;
1408     case(REGISTER_ANALYZE_GROUP_UNSORTED): toolspath = "/Analyze/"; break;
1409     case(REGISTER_ANALYZE_GROUP_CONVERSATION_FILTER): toolspath = "/Analyze/Conversation Filter/"; break;
1410     case(REGISTER_STAT_GROUP_TELEPHONY): toolspath = "/Telephony/"; break;
1411     case(REGISTER_TOOLS_GROUP_UNSORTED): toolspath = "/Tools/"; break;
1412     default:
1413         g_assert(!"no such menu group");
1414         toolspath = NULL;
1415     }
1416
1417     /* add the (empty) root node, if not already done */
1418     if(tap_menu_tree_root == NULL) {
1419         child = g_malloc0(sizeof (menu_item_t));
1420         tap_menu_tree_root = g_list_append(NULL, child);
1421     }
1422
1423     /*
1424      * Create any submenus required.
1425      */
1426     curnode = tap_menu_tree_root;
1427     p = name;
1428     while ((p = strchr(p, '/')) != NULL) {
1429         /*
1430          * OK, everything between "name" and "p" is
1431          * a menu relative subtree into which the menu item
1432          * will be placed.
1433          *
1434          * Construct the absolute path name of that subtree.
1435          */
1436         menupathlen = strlen(toolspath) + 1 + (p - name);
1437         menupath = g_malloc(menupathlen);
1438         g_strlcpy(menupath, toolspath, menupathlen);
1439         g_strlcat(menupath, name, menupathlen);
1440
1441         /*
1442          * Does there exist an entry with that path at this
1443          * level of the Analyze menu tree?
1444          */
1445         child = curnode->data;
1446         for (childnode = child->children; childnode != NULL; childnode = childnode->next) {
1447             child = childnode->data;
1448             if (strcmp(child->name, menupath) == 0)
1449                 break;
1450         }
1451         if (childnode == NULL) {
1452             /*
1453              * No.  Create such an item as a subtree, and
1454              * add it to the Tools menu tree.
1455              */
1456             childnode = tap_menu_item_add(
1457                 menupath, group, "", NULL, NULL ,NULL, NULL, curnode);
1458         } else {
1459             /*
1460              * Yes.  We don't need this "menupath" any longer.
1461              */
1462             g_free(menupath);
1463         }
1464         curnode = childnode;
1465
1466         /*
1467          * Skip over the '/' we found.
1468          */
1469         p++;
1470     }
1471
1472     /*
1473      * Construct the main menu path for the menu item.
1474      */
1475     menupathlen = strlen(toolspath) + 1 + strlen(name);
1476     menupath = g_malloc(menupathlen);
1477     g_strlcpy(menupath, toolspath, menupathlen);
1478     g_strlcat(menupath, name, menupathlen);
1479
1480     /*
1481      * Construct an item factory entry for the item, and add it to
1482      * the main menu.
1483      */
1484     tap_menu_item_add(
1485         menupath, group, stock_id, callback,
1486         selected_packet_enabled, selected_tree_row_enabled,
1487         callback_data, curnode);
1488 }
1489
1490
1491 void
1492 register_stat_menu_item(
1493     const char *name,
1494     register_stat_group_t group,
1495     GtkItemFactoryCallback callback,
1496     gboolean (*selected_packet_enabled)(frame_data *, epan_dissect_t *, gpointer callback_data),
1497     gboolean (*selected_tree_row_enabled)(field_info *, gpointer callback_data),
1498     gpointer callback_data)
1499 {
1500     register_stat_menu_item_stock(
1501         name,
1502         group,
1503         NULL,
1504         callback,
1505         selected_packet_enabled,
1506         selected_tree_row_enabled,
1507         callback_data);
1508 }
1509
1510 static guint merge_tap_menus_layered(GList *node, gint group) {
1511     GtkItemFactoryEntry *entry;
1512     GList       *child;
1513     guint       added = 0;
1514     menu_item_t *node_data = node->data;
1515
1516     /*
1517      * Is this a leaf node or an interior node?
1518      */
1519     if (node_data->children == NULL) {
1520         /*
1521          * It's a leaf node.
1522          */
1523
1524         /*
1525          * The root node doesn't correspond to a menu tree item; it
1526          * has a null name pointer.
1527          */
1528         if (node_data->name != NULL && group == node_data->group) {
1529             entry = g_malloc0(sizeof (GtkItemFactoryEntry));
1530             entry->path = node_data->name;
1531             entry->callback = node_data->callback;
1532             switch(group) {
1533             case(REGISTER_STAT_GROUP_UNSORTED):
1534                 break;
1535             case(REGISTER_STAT_GROUP_GENERIC):
1536                 break;
1537             case(REGISTER_STAT_GROUP_CONVERSATION_LIST):
1538                 entry->item_type = "<StockItem>";
1539                 entry->extra_data = WIRESHARK_STOCK_CONVERSATIONS;
1540                 break;
1541             case(REGISTER_STAT_GROUP_ENDPOINT_LIST):
1542                 entry->item_type = "<StockItem>";
1543                 entry->extra_data = WIRESHARK_STOCK_ENDPOINTS;
1544                 break;
1545             case(REGISTER_STAT_GROUP_RESPONSE_TIME):
1546                 entry->item_type = "<StockItem>";
1547                 entry->extra_data = WIRESHARK_STOCK_TIME;
1548                 break;
1549             case(REGISTER_STAT_GROUP_TELEPHONY):
1550                 break;
1551             case(REGISTER_ANALYZE_GROUP_UNSORTED):
1552                 break;
1553             case(REGISTER_ANALYZE_GROUP_CONVERSATION_FILTER):
1554                 break;
1555             case(REGISTER_TOOLS_GROUP_UNSORTED):
1556                 break;
1557             default:
1558                 g_assert_not_reached();
1559             }
1560             if(node_data->stock_id!= NULL) {
1561                 entry->item_type = "<StockItem>";
1562                 entry->extra_data = node_data->stock_id;
1563             }
1564             gtk_item_factory_create_item(main_menu_factory, entry, node_data->callback_data, /* callback_type */ 2);
1565             set_menu_sensitivity(main_menu_factory, node_data->name, FALSE); /* no capture file yet */
1566             added++;
1567             g_free(entry);
1568         }
1569     } else {
1570         /*
1571          * It's an interior node; call
1572          * "merge_tap_menus_layered()" on all its children
1573          */
1574
1575         /*
1576          * The root node doesn't correspond to a menu tree item; it
1577          * has a null name pointer.
1578          */
1579         if (node_data->name != NULL && group == node_data->group) {
1580             entry = g_malloc0(sizeof (GtkItemFactoryEntry));
1581             entry->path = node_data->name;
1582             entry->item_type = "<Branch>";
1583             gtk_item_factory_create_item(main_menu_factory, entry,
1584                 NULL, 2);
1585             set_menu_sensitivity(main_menu_factory, node_data->name,
1586                 FALSE);    /* no children yet */
1587             added++;
1588             g_free(entry);
1589         }
1590
1591         for (child = node_data->children; child != NULL; child =
1592             child->next) {
1593             added += merge_tap_menus_layered(child, group);
1594         }
1595     }
1596
1597     return added;
1598 }
1599
1600
1601 void merge_all_tap_menus(GList *node) {
1602     GtkItemFactoryEntry *sep_entry;
1603
1604     sep_entry = g_malloc0(sizeof (GtkItemFactoryEntry));
1605     sep_entry->item_type = "<Separator>";
1606     sep_entry->path = "/Statistics/";
1607
1608     /*
1609      * merge only the menu items of the specific group,
1610      * and then append a seperator
1611      */
1612     if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_GENERIC)) {
1613         gtk_item_factory_create_item(main_menu_factory, sep_entry, NULL, 2);
1614     }
1615     if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_CONVERSATION_LIST)) {
1616         /*gtk_item_factory_create_item(main_menu_factory, sep_entry, NULL, 2);*/
1617     }
1618     if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_ENDPOINT_LIST)) {
1619         /*gtk_item_factory_create_item(main_menu_factory, sep_entry, NULL, 2);*/
1620     }
1621     if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_RESPONSE_TIME)) {
1622         gtk_item_factory_create_item(main_menu_factory, sep_entry, NULL, 2);
1623     }
1624     if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_TELEPHONY)) {
1625         /*gtk_item_factory_create_item(main_menu_factory, sep_entry, NULL, 2);*/
1626     }
1627     if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_UNSORTED)) {
1628         /*gtk_item_factory_create_item(main_menu_factory, sep_entry, NULL, 2);*/
1629     }
1630     if (merge_tap_menus_layered(node, REGISTER_ANALYZE_GROUP_UNSORTED)) {
1631         sep_entry->path = "/Analyze/";
1632         /*gtk_item_factory_create_item(main_menu_factory, sep_entry, NULL, 2);*/
1633     }
1634     if (merge_tap_menus_layered(node, REGISTER_ANALYZE_GROUP_CONVERSATION_FILTER)) {
1635         sep_entry->path = "/Analyze/Conversation Filter/";
1636         /*gtk_item_factory_create_item(main_menu_factory, sep_entry, NULL, 2);*/
1637     }
1638     if (merge_tap_menus_layered(node, REGISTER_TOOLS_GROUP_UNSORTED)) {
1639         /*gtk_item_factory_create_item(main_menu_factory, sep_entry, NULL, 2);*/
1640     }
1641
1642     g_free (sep_entry);
1643 }
1644
1645
1646
1647 /*
1648  * Enable/disable menu sensitivity.
1649  */
1650 static void
1651 set_menu_sensitivity(GtkItemFactory *ifactory, const gchar *path, gint val)
1652 {
1653     GSList *menu_list;
1654     GtkWidget *menu_item;
1655     gchar *dup;
1656     gchar *dest;
1657
1658
1659     /* the underscore character regularly confuses things, as it will prevent finding
1660      * the menu_item, so it has to be removed first */
1661     dup = g_strdup(path);
1662     dest = dup;
1663     while(*path) {
1664         if (*path != '_') {
1665             *dest = *path;
1666             dest++;
1667         }
1668         path++;
1669     }
1670     *dest = '\0';
1671
1672     if (ifactory == NULL) {
1673         /*
1674          * Do it for all pop-up menus.
1675          */
1676         for (menu_list = popup_menu_list; menu_list != NULL;
1677              menu_list = g_slist_next(menu_list))
1678             set_menu_sensitivity(menu_list->data, dup, val);
1679     } else {
1680         /*
1681          * Do it for that particular menu.
1682          */
1683         if ((menu_item = gtk_item_factory_get_widget(ifactory, dup)) != NULL) {
1684             if (GTK_IS_MENU(menu_item)) {
1685                 /*
1686                  * "dup" refers to a submenu; "gtk_item_factory_get_widget()"
1687                  * gets the menu, not the item that, when selected, pops up
1688                  * the submenu.
1689                  *
1690                  * We have to change the latter item's sensitivity, so that
1691                  * it shows up normally if sensitive and grayed-out if
1692                  * insensitive.
1693                  */
1694                 menu_item = gtk_menu_get_attach_widget(GTK_MENU(menu_item));
1695             }
1696             gtk_widget_set_sensitive(menu_item, val);
1697         } else{
1698 #ifndef NEW_PACKET_LIST
1699             /* be sure this menu item *is* existing */
1700             g_assert_not_reached();
1701 #endif
1702         }
1703     }
1704
1705     g_free(dup);
1706 }
1707
1708 static void
1709 set_menu_object_data_meat(GtkItemFactory *ifactory, const gchar *path, const gchar *key, gpointer data)
1710 {
1711     GtkWidget *menu = NULL;
1712
1713     if ((menu = gtk_item_factory_get_widget(ifactory, path)) != NULL)
1714         g_object_set_data(G_OBJECT(menu), key, data);
1715 }
1716
1717 void
1718 set_menu_object_data (const gchar *path, const gchar *key, gpointer data) {
1719     GSList *menu_list = popup_menu_list;
1720     gchar *shortpath = strrchr(path, '/');
1721
1722     set_menu_object_data_meat(main_menu_factory, path, key, data);
1723     while (menu_list != NULL) {
1724         set_menu_object_data_meat(menu_list->data, shortpath, key, data);
1725         set_menu_object_data_meat(menu_list->data, path, key, data);
1726         menu_list = g_slist_next(menu_list);
1727     }
1728 }
1729
1730
1731 /* Recently used capture files submenu:
1732  * Submenu containing the recently used capture files.
1733  * The capture filenames are always kept with the absolute path, to be independant
1734  * of the current path.
1735  * They are only stored inside the labels of the submenu (no separate list). */
1736
1737 #define MENU_RECENT_FILES_PATH "/File/Open Recent"
1738 #define MENU_RECENT_FILES_KEY "Recent File Name"
1739
1740
1741
1742 static void
1743 update_menu_recent_capture_file1(GtkWidget *widget, gpointer cnt) {
1744     gchar *widget_cf_name;
1745
1746     widget_cf_name = g_object_get_data(G_OBJECT(widget), MENU_RECENT_FILES_KEY);
1747
1748     /* if this menu item is a file, count it */
1749     if (widget_cf_name) {
1750         (*(guint *)cnt)++;
1751         main_welcome_add_recent_capture_files(widget_cf_name);
1752     }
1753 }
1754
1755
1756
1757 /* update the menu */
1758 static void
1759 update_menu_recent_capture_file(GtkWidget *submenu_recent_files) {
1760     guint cnt = 0;
1761
1762
1763     main_welcome_reset_recent_capture_files();
1764
1765     gtk_container_foreach(GTK_CONTAINER(submenu_recent_files),
1766                           update_menu_recent_capture_file1, &cnt);
1767
1768     /* make parent menu item sensitive only, if we have any valid files in the list */
1769     set_menu_sensitivity(main_menu_factory, MENU_RECENT_FILES_PATH, cnt);
1770 }
1771
1772
1773
1774 /* remove the capture filename from the "Recent Files" menu */
1775 static void
1776 remove_menu_recent_capture_filename(gchar *cf_name) {
1777     GtkWidget *submenu_recent_files;
1778     GList* child_list;
1779     GList* child_list_item;
1780     GtkWidget    *menu_item_child;
1781     const gchar *menu_item_cf_name;
1782     
1783
1784     /* get the submenu container item */
1785     submenu_recent_files = gtk_item_factory_get_widget(main_menu_factory, MENU_RECENT_FILES_PATH);
1786
1787     /* find the corresponding menu item to be removed */
1788     child_list = gtk_container_get_children(GTK_CONTAINER(submenu_recent_files));
1789     child_list_item = child_list;
1790     while(child_list_item) {
1791         menu_item_child = (GTK_BIN(child_list_item->data))->child;
1792         if (menu_item_child != NULL) { /* Note: there are two "extra" items on the end of the child_list: */
1793                                        /*  - a separator (with no menu_item_child and thus no text label) */
1794                                        /*  - a 2nd item with a menu_child with text label "Clear"         */
1795                                        /*       [See add_menu_recent_capture_file_absolute() ]            */
1796                                        /* 'if (menu_item_child != NULL)' skips the separator item;        */
1797                                        /* An absolute filename in cf_name will never match  "Clear".      */
1798             menu_item_cf_name = gtk_label_get_text(GTK_LABEL(menu_item_child));
1799             if(strcmp(menu_item_cf_name, cf_name) == 0) {
1800                 /* XXX: is this all we need to do, to free the menu item and its label?
1801                    The reference count of widget will go to 0, so it'll be freed;
1802                    will that free the label? */
1803                 gtk_container_remove(GTK_CONTAINER(submenu_recent_files), child_list_item->data);
1804             }
1805         }
1806         child_list_item = g_list_next(child_list_item);
1807     }
1808     g_list_free(child_list);
1809
1810     update_menu_recent_capture_file(submenu_recent_files);
1811 }
1812
1813
1814 /* remove the capture filename from the "Recent Files" menu */
1815 static void
1816 remove_menu_recent_capture_file(GtkWidget *widget, gpointer unused _U_) {
1817     GtkWidget *submenu_recent_files;
1818     gchar *widget_cf_name;
1819
1820
1821     widget_cf_name = g_object_get_data(G_OBJECT(widget), MENU_RECENT_FILES_KEY);
1822     g_free(widget_cf_name);
1823
1824     /* get the submenu container item */
1825     submenu_recent_files = gtk_item_factory_get_widget(main_menu_factory, MENU_RECENT_FILES_PATH);
1826
1827     /* XXX: is this all we need to do, to free the menu item and its label?
1828        The reference count of widget will go to 0, so it'll be freed;
1829        will that free the label? */
1830     gtk_container_remove(GTK_CONTAINER(submenu_recent_files), widget);
1831 }
1832
1833
1834 /* callback, if the user pushed the <Clear> menu item */
1835 static void
1836 clear_menu_recent_capture_file_cmd_cb(GtkWidget *w _U_, gpointer unused _U_) {
1837     GtkWidget *submenu_recent_files;
1838
1839
1840     submenu_recent_files = gtk_item_factory_get_widget(main_menu_factory, MENU_RECENT_FILES_PATH);
1841
1842     gtk_container_foreach(GTK_CONTAINER(submenu_recent_files),
1843                           remove_menu_recent_capture_file, NULL);
1844
1845     update_menu_recent_capture_file(submenu_recent_files);
1846 }
1847
1848
1849 /* Open a file by it's name
1850    (Beware: will not ask to close existing capture file!) */
1851 void
1852 menu_open_filename(gchar *cf_name)
1853 {
1854     GtkWidget *submenu_recent_files;
1855     int       err;
1856
1857     submenu_recent_files = gtk_item_factory_get_widget(main_menu_factory, MENU_RECENT_FILES_PATH);
1858
1859     /* open and read the capture file (this will close an existing file) */
1860     if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
1861         cf_read(&cfile);
1862     } else {
1863         /* the capture file apparently no longer exists; remove menu item    */
1864         /* XXX: ask user to remove item, it's maybe only a temporary problem */
1865         remove_menu_recent_capture_filename(cf_name);
1866     }
1867
1868     update_menu_recent_capture_file(submenu_recent_files);
1869 }
1870
1871
1872 /* callback, if the user pushed a recent file submenu item */
1873 void
1874 menu_open_recent_file_cmd(GtkWidget *w)
1875 {
1876     GtkWidget   *submenu_recent_files;
1877     GtkWidget   *menu_item_child;
1878     const gchar *cf_name;
1879     int         err;
1880
1881     submenu_recent_files = gtk_item_factory_get_widget(main_menu_factory, MENU_RECENT_FILES_PATH);
1882
1883     /* get capture filename from the menu item label */
1884     menu_item_child = (GTK_BIN(w))->child;
1885     cf_name = gtk_label_get_text(GTK_LABEL(menu_item_child));
1886
1887     /* open and read the capture file (this will close an existing file) */
1888     if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
1889         cf_read(&cfile);
1890     } else {
1891         /* the capture file apparently no longer exists; remove menu item    */
1892         /* XXX: ask user to remove item, it's maybe only a temporary problem */
1893         remove_menu_recent_capture_file(w, NULL);
1894     }
1895
1896     update_menu_recent_capture_file(submenu_recent_files);
1897 }
1898
1899 static void menu_open_recent_file_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
1900 {
1901     switch(btn) {
1902     case(ESD_BTN_YES):
1903         /* save file first */
1904         file_save_as_cmd(after_save_open_recent_file, data);
1905         break;
1906     case(ESD_BTN_NO):
1907         cf_close(&cfile);
1908         menu_open_recent_file_cmd(data);
1909         break;
1910     case(ESD_BTN_CANCEL):
1911         break;
1912     default:
1913         g_assert_not_reached();
1914     }
1915 }
1916
1917 static void
1918 menu_open_recent_file_cmd_cb(GtkWidget *widget, gpointer data _U_) {
1919     gpointer  dialog;
1920
1921
1922     if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
1923         /* user didn't saved his current file, ask him */
1924         dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO_CANCEL,
1925                                "%sSave capture file before opening a new one?%s\n\n"
1926                                "If you open a new capture file without saving, your current capture data will be discarded.",
1927                                simple_dialog_primary_start(), simple_dialog_primary_end());
1928         simple_dialog_set_cb(dialog, menu_open_recent_file_answered_cb, widget);
1929     } else {
1930         /* unchanged file */
1931         menu_open_recent_file_cmd(widget);
1932     }
1933 }
1934
1935 /* add the capture filename (with an absolute path) to the "Recent Files" menu */
1936 static void
1937 add_menu_recent_capture_file_absolute(gchar *cf_name) {
1938     GtkWidget *submenu_recent_files;
1939     GList *menu_item_list;
1940     GList *li;
1941     gchar *widget_cf_name;
1942     gchar *normalized_cf_name;
1943     GtkWidget *menu_item;
1944     guint cnt;
1945
1946
1947
1948     normalized_cf_name = g_strdup(cf_name);
1949 #ifdef _WIN32
1950     /* replace all slashes by backslashes */
1951     g_strdelimit(normalized_cf_name, "/", '\\');
1952 #endif
1953
1954     /* get the submenu container item */
1955     submenu_recent_files = gtk_item_factory_get_widget(main_menu_factory, MENU_RECENT_FILES_PATH);
1956
1957     /* convert container to a GList */
1958     menu_item_list = gtk_container_get_children(GTK_CONTAINER(submenu_recent_files));
1959
1960     /* iterate through list items of menu_item_list,
1961      * removing special items, a maybe duplicate entry and every item above count_max */
1962     cnt = 1;
1963     for (li = g_list_first(menu_item_list); li; li = li->next, cnt++) {
1964         /* get capture filename */
1965         menu_item = GTK_WIDGET(li->data);
1966         widget_cf_name = g_object_get_data(G_OBJECT(menu_item), MENU_RECENT_FILES_KEY);
1967
1968         /* if this element string is one of our special items (seperator, ...) or
1969          * already in the list or
1970          * this element is above maximum count (too old), remove it */
1971         if (!widget_cf_name ||
1972 #ifdef _WIN32
1973             /* do a case insensitive compare on win32 */
1974             g_ascii_strncasecmp(widget_cf_name, normalized_cf_name, 1000) == 0 ||
1975 #else   /* _WIN32 */
1976             /* do a case sensitive compare on unix */
1977             strncmp(widget_cf_name, normalized_cf_name, 1000) == 0 ||
1978 #endif
1979             cnt >= prefs.gui_recent_files_count_max) {
1980             remove_menu_recent_capture_file(li->data, NULL);
1981             cnt--;
1982         }
1983     }
1984
1985     g_list_free(menu_item_list);
1986
1987     /* add new item at latest position */
1988     menu_item = gtk_menu_item_new_with_label(normalized_cf_name);
1989     g_object_set_data(G_OBJECT(menu_item), MENU_RECENT_FILES_KEY, normalized_cf_name);
1990     gtk_menu_shell_prepend (GTK_MENU_SHELL(submenu_recent_files), menu_item);
1991     g_signal_connect_swapped(GTK_OBJECT(menu_item), "activate",
1992                              G_CALLBACK(menu_open_recent_file_cmd_cb), (GtkObject *) menu_item);
1993     gtk_widget_show (menu_item);
1994
1995     /* add seperator at last position */
1996     menu_item = gtk_menu_item_new();
1997     gtk_menu_shell_append (GTK_MENU_SHELL(submenu_recent_files), menu_item);
1998     gtk_widget_show (menu_item);
1999
2000     /* add new "clear list" item at last position */
2001     menu_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_CLEAR, NULL);
2002     gtk_menu_shell_append (GTK_MENU_SHELL(submenu_recent_files), menu_item);
2003     g_signal_connect_swapped(GTK_OBJECT(menu_item), "activate",
2004                              G_CALLBACK(clear_menu_recent_capture_file_cmd_cb), (GtkObject *) menu_item);
2005     gtk_widget_show (menu_item);
2006
2007     update_menu_recent_capture_file(submenu_recent_files);
2008 }
2009
2010
2011 /* add the capture filename to the "Recent Files" menu */
2012 /* (will change nothing, if this filename is already in the menu) */
2013 /*
2014  * XXX - We might want to call SHAddToRecentDocs under Windows 7:
2015  * http://stackoverflow.com/questions/437212/how-do-you-register-a-most-recently-used-list-with-windows-in-preparation-for-win
2016  */
2017 void
2018 add_menu_recent_capture_file(gchar *cf_name) {
2019     gchar *curr;
2020     gchar *absolute;
2021
2022
2023     /* if this filename is an absolute path, we can use it directly */
2024     if (g_path_is_absolute(cf_name)) {
2025         add_menu_recent_capture_file_absolute(cf_name);
2026         return;
2027     }
2028
2029     /* this filename is not an absolute path, prepend the current dir */
2030     curr = g_get_current_dir();
2031     absolute = g_strdup_printf("%s%s%s", curr, G_DIR_SEPARATOR_S, cf_name);
2032     add_menu_recent_capture_file_absolute(absolute);
2033     g_free(curr);
2034     g_free(absolute);
2035 }
2036
2037
2038 /* write all capture filenames of the menu to the user's recent file */
2039 void
2040 menu_recent_file_write_all(FILE *rf) {
2041     GtkWidget   *submenu_recent_files;
2042     GList       *children;
2043     GList       *child;
2044     gchar       *cf_name;
2045
2046
2047     submenu_recent_files = gtk_item_factory_get_widget(main_menu_factory, MENU_RECENT_FILES_PATH);
2048
2049     /* we have to iterate backwards through the children's list,
2050      * so we get the latest item last in the file.
2051      * (don't use gtk_container_foreach() here, it will return the wrong iteration order) */
2052     children = gtk_container_get_children(GTK_CONTAINER(submenu_recent_files));
2053     child = g_list_last(children);
2054     while(child != NULL) {
2055         /* get capture filename from the menu item label */
2056         cf_name = g_object_get_data(G_OBJECT(child->data), MENU_RECENT_FILES_KEY);
2057         if (cf_name) {
2058             if(u3_active())
2059                 fprintf (rf, RECENT_KEY_CAPTURE_FILE ": %s\n", u3_contract_device_path(cf_name));
2060             else
2061                 fprintf (rf, RECENT_KEY_CAPTURE_FILE ": %s\n", cf_name);
2062         }
2063
2064         child = g_list_previous(child);
2065     }
2066
2067     g_list_free(children);
2068 }
2069
2070
2071 static void
2072 show_hide_cb(GtkWidget *w, gpointer data _U_, gint action)
2073 {
2074
2075     /* save current setting in recent */
2076     switch(action) {
2077         case(SHOW_HIDE_MAIN_TOOLBAR):
2078         recent.main_toolbar_show = GTK_CHECK_MENU_ITEM(w)->active;
2079         break;
2080         case(SHOW_HIDE_FILTER_TOOLBAR):
2081         recent.filter_toolbar_show = GTK_CHECK_MENU_ITEM(w)->active;
2082         break;
2083 #ifdef HAVE_AIRPCAP
2084         case(SHOW_HIDE_AIRPCAP_TOOLBAR):
2085         recent.airpcap_toolbar_show = GTK_CHECK_MENU_ITEM(w)->active;
2086         break;
2087 #endif
2088         case(SHOW_HIDE_STATUSBAR):
2089         recent.statusbar_show = GTK_CHECK_MENU_ITEM(w)->active;
2090         break;
2091         case(SHOW_HIDE_PACKET_LIST):
2092         recent.packet_list_show = GTK_CHECK_MENU_ITEM(w)->active;
2093         break;
2094         case(SHOW_HIDE_TREE_VIEW):
2095         recent.tree_view_show = GTK_CHECK_MENU_ITEM(w)->active;
2096         break;
2097         case(SHOW_HIDE_BYTE_VIEW):
2098         recent.byte_view_show = GTK_CHECK_MENU_ITEM(w)->active;
2099         break;
2100         default:
2101             g_assert_not_reached();
2102     }
2103
2104     main_widgets_show_or_hide();
2105 }
2106
2107
2108 static void
2109 timestamp_format_cb(GtkWidget *w _U_, gpointer d _U_, gint action)
2110 {
2111     if (recent.gui_time_format != action) {
2112         timestamp_set_type(action);
2113         recent.gui_time_format = action;
2114 #ifdef NEW_PACKET_LIST
2115                 /* This call adjusts column width */
2116                 cf_timestamp_auto_precision(&cfile);            
2117                 new_packet_list_queue_draw();
2118 #else
2119         cf_change_time_formats(&cfile);
2120 #endif
2121     }
2122 }
2123
2124
2125 static void
2126 timestamp_precision_cb(GtkWidget *w _U_, gpointer d _U_, gint action)
2127 {
2128     if (recent.gui_time_precision != action) {
2129         /* the actual precision will be set in cf_change_time_formats() below */
2130         if (action == TS_PREC_AUTO) {
2131             timestamp_set_precision(TS_PREC_AUTO_SEC);
2132         } else {
2133             timestamp_set_precision(action);
2134         }
2135         recent.gui_time_precision  = action;
2136 #ifdef NEW_PACKET_LIST
2137                 /* This call adjusts column width */
2138                 cf_timestamp_auto_precision(&cfile);
2139                 new_packet_list_queue_draw();
2140 #else
2141         cf_change_time_formats(&cfile);
2142 #endif
2143     }
2144 }
2145
2146
2147 void
2148 menu_name_resolution_changed(void)
2149 {
2150     GtkWidget *menu = NULL;
2151
2152     menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Name Resolution/Enable for MAC Layer");
2153     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), g_resolv_flags & RESOLV_MAC);
2154
2155     menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Name Resolution/Enable for Network Layer");
2156     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), g_resolv_flags & RESOLV_NETWORK);
2157
2158     menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Name Resolution/Enable for Transport Layer");
2159     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), g_resolv_flags & RESOLV_TRANSPORT);
2160 }
2161
2162 static void
2163 name_resolution_cb(GtkWidget *w, gpointer d _U_, gint action)
2164 {
2165     if (GTK_CHECK_MENU_ITEM(w)->active) {
2166         g_resolv_flags |= action;
2167     } else {
2168         g_resolv_flags &= ~action;
2169     }
2170 }
2171
2172 #ifdef HAVE_LIBPCAP
2173 void
2174 menu_auto_scroll_live_changed(gboolean auto_scroll_live_in) {
2175     GtkWidget *menu;
2176
2177
2178     /* tell menu about it */
2179     menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Auto Scroll in Live Capture");
2180     if( ((gboolean) GTK_CHECK_MENU_ITEM(menu)->active) != auto_scroll_live_in) {
2181         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), auto_scroll_live_in);
2182     }
2183
2184     /* tell toolbar about it */
2185     toolbar_auto_scroll_live_changed(auto_scroll_live_in);
2186
2187     /* change auto scroll */
2188     if(auto_scroll_live_in != auto_scroll_live) {
2189         auto_scroll_live  = auto_scroll_live_in;
2190     }
2191 }
2192
2193 static void
2194 auto_scroll_live_cb(GtkWidget *w _U_, gpointer d _U_)
2195 {
2196     menu_auto_scroll_live_changed(GTK_CHECK_MENU_ITEM(w)->active);
2197 }
2198 #endif
2199
2200
2201 void
2202 menu_colorize_changed(gboolean packet_list_colorize) {
2203     GtkWidget *menu;
2204
2205
2206     /* tell menu about it */
2207     menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Colorize Packet List");
2208     if( ((gboolean) GTK_CHECK_MENU_ITEM(menu)->active) != packet_list_colorize) {
2209         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), packet_list_colorize);
2210     }
2211
2212     /* tell toolbar about it */
2213     toolbar_colorize_changed(packet_list_colorize);
2214
2215     /* change colorization */
2216     if(packet_list_colorize != recent.packet_list_colorize) {
2217         recent.packet_list_colorize = packet_list_colorize;
2218         color_filters_enable(packet_list_colorize);
2219 #ifdef NEW_PACKET_LIST
2220                 new_packet_list_colorize_packets();
2221 #else
2222         cf_colorize_packets(&cfile);
2223 #endif
2224     }
2225 }
2226
2227 static void
2228 colorize_cb(GtkWidget *w, gpointer d _U_)
2229 {
2230     menu_colorize_changed(GTK_CHECK_MENU_ITEM(w)->active);
2231 }
2232
2233
2234 /* the recent file read has finished, update the menu corresponding */
2235 void
2236 menu_recent_read_finished(void) {
2237     GtkWidget *menu = NULL;
2238
2239     menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Main Toolbar");
2240     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), recent.main_toolbar_show);
2241
2242     menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Filter Toolbar");
2243     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), recent.filter_toolbar_show);
2244
2245 #ifdef HAVE_AIRPCAP
2246     menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Wireless Toolbar");
2247     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), recent.airpcap_toolbar_show);
2248 #endif
2249
2250     menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Statusbar");
2251     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), recent.statusbar_show);
2252
2253     menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Packet List");
2254     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), recent.packet_list_show);
2255
2256     menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Packet Details");
2257     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), recent.tree_view_show);
2258
2259     menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Packet Bytes");
2260     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), recent.byte_view_show);
2261
2262     menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Colorize Packet List");
2263     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), recent.packet_list_colorize);
2264
2265     menu_name_resolution_changed();
2266
2267 #ifdef HAVE_LIBPCAP
2268     menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Auto Scroll in Live Capture");
2269     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), auto_scroll_live);
2270 #endif
2271
2272     main_widgets_rearrange();
2273
2274     /* don't change the time format, if we had a command line value */
2275     if (timestamp_get_type() != TS_NOT_SET) {
2276         recent.gui_time_format = timestamp_get_type();
2277     }
2278
2279     switch(recent.gui_time_format) {
2280     case(TS_ABSOLUTE_WITH_DATE):
2281         menu = gtk_item_factory_get_widget(main_menu_factory,
2282             "/View/Time Display Format/Date and Time of Day:   1970-01-01 01:02:03.123456");
2283         break;
2284     case(TS_ABSOLUTE):
2285         menu = gtk_item_factory_get_widget(main_menu_factory,
2286             "/View/Time Display Format/Time of Day:   01:02:03.123456");
2287         break;
2288     case(TS_RELATIVE):
2289         menu = gtk_item_factory_get_widget(main_menu_factory,
2290             "/View/Time Display Format/Seconds Since Beginning of Capture:   123.123456");
2291         break;
2292     case(TS_DELTA):
2293         menu = gtk_item_factory_get_widget(main_menu_factory,
2294             "/View/Time Display Format/Seconds Since Previous Captured Packet:   1.123456");
2295         break;
2296     case(TS_DELTA_DIS):
2297         menu = gtk_item_factory_get_widget(main_menu_factory,
2298             "/View/Time Display Format/Seconds Since Previous Displayed Packet:   1.123456");
2299         break;
2300     case(TS_EPOCH):
2301         menu = gtk_item_factory_get_widget(main_menu_factory,
2302             "/View/Time Display Format/Seconds Since Epoch (1970-01-01):   1234567890.123456");
2303         break;
2304     default:
2305         g_assert_not_reached();
2306     }
2307
2308     /* set_active will not trigger the callback when activating an active item! */
2309     recent.gui_time_format = -1;
2310     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), FALSE);
2311     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE);
2312
2313     switch(recent.gui_time_precision) {
2314     case(TS_PREC_AUTO):
2315         menu = gtk_item_factory_get_widget(main_menu_factory,
2316             "/View/Time Display Format/Automatic (File Format Precision)");
2317         break;
2318     case(TS_PREC_FIXED_SEC):
2319         menu = gtk_item_factory_get_widget(main_menu_factory,
2320             "/View/Time Display Format/Seconds:   0");
2321         break;
2322     case(TS_PREC_FIXED_DSEC):
2323         menu = gtk_item_factory_get_widget(main_menu_factory,
2324             "/View/Time Display Format/Deciseconds:   0.1");
2325         break;
2326     case(TS_PREC_FIXED_CSEC):
2327         menu = gtk_item_factory_get_widget(main_menu_factory,
2328             "/View/Time Display Format/Centiseconds:   0.12");
2329         break;
2330     case(TS_PREC_FIXED_MSEC):
2331         menu = gtk_item_factory_get_widget(main_menu_factory,
2332             "/View/Time Display Format/Milliseconds:   0.123");
2333         break;
2334     case(TS_PREC_FIXED_USEC):
2335         menu = gtk_item_factory_get_widget(main_menu_factory,
2336             "/View/Time Display Format/Microseconds:   0.123456");
2337         break;
2338     case(TS_PREC_FIXED_NSEC):
2339         menu = gtk_item_factory_get_widget(main_menu_factory,
2340             "/View/Time Display Format/Nanoseconds:   0.123456789");
2341         break;
2342     default:
2343         g_assert_not_reached();
2344     }
2345
2346     /* set_active will not trigger the callback when activating an active item! */
2347     recent.gui_time_precision = -1;
2348     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), FALSE);
2349     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE);
2350
2351     menu_colorize_changed(recent.packet_list_colorize);
2352
2353     switch (recent.gui_bytes_view) {
2354     case BYTES_HEX:
2355         menu = gtk_item_factory_get_widget(bytes_menu_factory, "/Hex View");
2356         break;
2357     case BYTES_BITS:
2358         menu = gtk_item_factory_get_widget(bytes_menu_factory, "/Bits View");
2359         break;
2360     default:
2361         g_assert_not_reached();
2362     }
2363     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE);
2364 }
2365
2366
2367 gint
2368 popup_menu_handler(GtkWidget *widget, GdkEvent *event, gpointer data)
2369 {
2370     GtkWidget *menu = (GtkWidget *)data;
2371     GdkEventButton *event_button = NULL;
2372     gint row, column;
2373
2374     if(widget == NULL || event == NULL || data == NULL) {
2375         return FALSE;
2376     }
2377
2378     /*
2379      * If we ever want to make the menu differ based on what row
2380      * and/or column we're above, we'd use "eth_clist_get_selection_info()"
2381      * to find the row and column number for the coordinates; a CTree is,
2382      * I guess, like a CList with one column(?) and the expander widget
2383      * as a pixmap.
2384      */
2385     /* Check if we are on packet_list object */
2386     if (widget == g_object_get_data(G_OBJECT(popup_menu_object), E_MPACKET_LIST_KEY) &&
2387         ((GdkEventButton *)event)->button != 1) {
2388 #ifdef NEW_PACKET_LIST
2389         gint physical_row;
2390         if (new_packet_list_get_event_row_column((GdkEventButton *)event, &physical_row, &row, &column)) {
2391 #else
2392         if (packet_list_get_event_row_column(widget, (GdkEventButton *)event, &row, &column)) {
2393 #endif
2394             g_object_set_data(G_OBJECT(popup_menu_object), E_MPACKET_LIST_ROW_KEY,
2395 #ifdef NEW_PACKET_LIST
2396                             GINT_TO_POINTER(physical_row));
2397 #else
2398                             GINT_TO_POINTER(row));
2399 #endif
2400             g_object_set_data(G_OBJECT(popup_menu_object), E_MPACKET_LIST_COL_KEY,
2401                             GINT_TO_POINTER(column));
2402 #ifdef NEW_PACKET_LIST
2403             new_packet_list_set_selected_row(row);
2404 #else
2405             packet_list_set_selected_row(row);
2406 #endif
2407         }
2408     }
2409
2410     /* Check if we are on tree_view object */
2411     if (widget == tree_view) {
2412         tree_view_select(widget, (GdkEventButton *) event);
2413     }
2414
2415     /* context menu handler */
2416     if(event->type == GDK_BUTTON_PRESS) {
2417         event_button = (GdkEventButton *) event;
2418
2419         /* To qoute the "Gdk Event Structures" doc:
2420          * "Normally button 1 is the left mouse button, 2 is the middle button, and 3 is the right button" */
2421         if(event_button->button == 3) {
2422             gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
2423                            event_button->button,
2424                            event_button->time);
2425             g_signal_stop_emission_by_name(widget, "button_press_event");
2426             return TRUE;
2427         }
2428     }
2429
2430     /* Check if we are on byte_view object */
2431     if(widget == get_notebook_bv_ptr(byte_nb_ptr)) {
2432         byte_view_select(widget, (GdkEventButton *) event);
2433     }
2434
2435     /* GDK_2BUTTON_PRESS is a doubleclick -> expand/collapse tree row */
2436     /* GTK version 1 seems to be doing this automatically */
2437     if (widget == tree_view && event->type == GDK_2BUTTON_PRESS) {
2438         GtkTreePath      *path;
2439
2440         if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget),
2441                                           (gint) (((GdkEventButton *)event)->x),
2442                                           (gint) (((GdkEventButton *)event)->y),
2443                                           &path, NULL, NULL, NULL))
2444         {
2445             if (gtk_tree_view_row_expanded(GTK_TREE_VIEW(widget), path))
2446                 gtk_tree_view_collapse_row(GTK_TREE_VIEW(widget), path);
2447             else
2448                 gtk_tree_view_expand_row(GTK_TREE_VIEW(widget), path,
2449                                          FALSE);
2450             gtk_tree_path_free(path);
2451         }
2452     }
2453     return FALSE;
2454 }
2455
2456 /* Enable or disable menu items based on whether you have a capture file
2457    you've finished reading and, if you have one, whether it's been saved
2458    and whether it could be saved except by copying the raw packet data. */
2459 void
2460 set_menus_for_capture_file(capture_file *cf)
2461 {
2462     if (cf == NULL) {
2463         /* We have no capture file */
2464         set_menu_sensitivity(main_menu_factory, "/File/Merge...", FALSE);
2465         set_menu_sensitivity(main_menu_factory, "/File/Close", FALSE);
2466         set_menu_sensitivity(main_menu_factory, "/File/Save", FALSE);
2467         set_menu_sensitivity(main_menu_factory, "/File/Save As...", FALSE);
2468         set_menu_sensitivity(main_menu_factory, "/File/Export", FALSE);
2469         set_menu_sensitivity(main_menu_factory, "/View/Reload", FALSE);
2470         set_toolbar_for_capture_file(FALSE);
2471         set_toolbar_for_unsaved_capture_file(FALSE);
2472     } else {
2473         set_menu_sensitivity(main_menu_factory, "/File/Merge...", TRUE);
2474         set_menu_sensitivity(main_menu_factory, "/File/Close", TRUE);
2475         set_menu_sensitivity(main_menu_factory, "/File/Save", !cf->user_saved);
2476         /*
2477          * "Save As..." works only if we can write the file out in at least
2478          * one format (so we can save the whole file or just a subset) or
2479          * if we have an unsaved capture (so writing the whole file out
2480          * with a raw data copy makes sense).
2481          */
2482         set_menu_sensitivity(main_menu_factory, "/File/Save As...",
2483                              cf_can_save_as(cf) || !cf->user_saved);
2484         set_menu_sensitivity(main_menu_factory, "/File/Export", TRUE);
2485         set_menu_sensitivity(main_menu_factory, "/View/Reload", TRUE);
2486         set_toolbar_for_unsaved_capture_file(!cf->user_saved);
2487         set_toolbar_for_capture_file(TRUE);
2488     }
2489 }
2490
2491 /* Enable or disable menu items based on whether there's a capture in
2492    progress. */
2493 void
2494 set_menus_for_capture_in_progress(gboolean capture_in_progress)
2495 {
2496     set_menu_sensitivity(main_menu_factory, "/File/Open...",
2497                          !capture_in_progress);
2498     set_menu_sensitivity(main_menu_factory, "/File/Open Recent",
2499                          !capture_in_progress);
2500     set_menu_sensitivity(main_menu_factory, "/File/Export",
2501                          capture_in_progress);
2502 #ifdef HAVE_LIBPCAP
2503     set_menu_sensitivity(main_menu_factory, "/Capture/Options...",
2504                          !capture_in_progress);
2505     set_menu_sensitivity(main_menu_factory, "/Capture/Start",
2506                          !capture_in_progress);
2507     set_menu_sensitivity(main_menu_factory, "/Capture/Stop",
2508                          capture_in_progress);
2509     set_menu_sensitivity(main_menu_factory, "/Capture/Restart",
2510                          capture_in_progress);
2511     set_toolbar_for_capture_in_progress(capture_in_progress);
2512
2513     set_capture_if_dialog_for_capture_in_progress(capture_in_progress);
2514 #endif /* HAVE_LIBPCAP */
2515 }
2516
2517 /* Enable or disable menu items based on whether you have some captured
2518    packets. */
2519 static gboolean
2520 walk_menu_tree_for_captured_packets(GList *node,
2521     gboolean have_captured_packets)
2522 {
2523     gboolean    is_enabled;
2524     GList       *child;
2525     menu_item_t *node_data = node->data;
2526
2527     /*
2528      * Is this a leaf node or an interior node?
2529      */
2530     if (node_data->children == NULL) {
2531         /*
2532          * It's a leaf node.
2533          *
2534          * If it has no "selected_packet_enabled()" or
2535          * "selected_tree_row_enabled()" routines, we enable
2536          * it.  This allows tap windows to be popped up even
2537          * if you have no capture file; this is done to let
2538          * the user pop up multiple tap windows before reading
2539          * in a capture file, so that they can be processed in
2540          * parallel while the capture file is being read rather
2541          * than one at at time as you pop up the windows, and to
2542          * let the user pop up tap windows before starting an
2543          * "Update list of packets in real time" capture, so that
2544          * the statistics can be displayed while the capture is
2545          * in progress.
2546          *
2547          * If it has either of those routines, we disable it for
2548          * now - as long as, when a capture is first available,
2549          * we don't get called after a packet or tree row is
2550          * selected, that's OK.
2551          * XXX - that should be done better.
2552          */
2553         if (node_data->selected_packet_enabled == NULL &&
2554             node_data->selected_tree_row_enabled == NULL)
2555             node_data->enabled = TRUE;
2556         else
2557             node_data->enabled = FALSE;
2558     } else {
2559         /*
2560          * It's an interior node; call
2561          * "walk_menu_tree_for_captured_packets()" on all its
2562          * children and, if any of them are enabled, enable
2563          * this node, otherwise disable it.
2564          *
2565          * XXX - should we just leave all interior nodes enabled?
2566          * Which is a better UI choice?
2567          */
2568         is_enabled = FALSE;
2569         for (child = node_data->children; child != NULL; child =
2570                  child->next) {
2571             if (walk_menu_tree_for_captured_packets(child,
2572                                                     have_captured_packets))
2573                 is_enabled = TRUE;
2574         }
2575         node_data->enabled = is_enabled;
2576     }
2577
2578     /*
2579      * The root node doesn't correspond to a menu tree item; it
2580      * has a null name pointer.
2581      */
2582     if (node_data->name != NULL) {
2583         set_menu_sensitivity(main_menu_factory, node_data->name,
2584                              node_data->enabled);
2585     }
2586     return node_data->enabled;
2587 }
2588
2589 void
2590 set_menus_for_captured_packets(gboolean have_captured_packets)
2591 {
2592     set_menu_sensitivity(main_menu_factory, "/File/Print...",
2593                          have_captured_packets);
2594     set_menu_sensitivity(packet_list_menu_factory, "/Print...",
2595                          have_captured_packets);
2596     set_menu_sensitivity(main_menu_factory, "/Edit/Find Packet...",
2597                          have_captured_packets);
2598     set_menu_sensitivity(main_menu_factory, "/Edit/Find Next",
2599                          have_captured_packets);
2600     set_menu_sensitivity(main_menu_factory, "/Edit/Find Previous",
2601                          have_captured_packets);
2602     set_menu_sensitivity(main_menu_factory, "/View/Zoom In",
2603                          have_captured_packets);
2604     set_menu_sensitivity(main_menu_factory, "/View/Zoom Out",
2605                          have_captured_packets);
2606     set_menu_sensitivity(main_menu_factory, "/View/Normal Size",
2607                          have_captured_packets);
2608     set_menu_sensitivity(main_menu_factory, "/Go/Go to Packet...",
2609                          have_captured_packets);
2610     set_menu_sensitivity(main_menu_factory, "/Go/Previous Packet",
2611                          have_captured_packets);
2612     set_menu_sensitivity(main_menu_factory, "/Go/Next Packet",
2613                          have_captured_packets);
2614     set_menu_sensitivity(main_menu_factory, "/Go/First Packet",
2615                          have_captured_packets);
2616     set_menu_sensitivity(main_menu_factory, "/Go/Last Packet",
2617                          have_captured_packets);
2618     set_menu_sensitivity(main_menu_factory, "/Statistics/Summary",
2619                          have_captured_packets);
2620     set_menu_sensitivity(main_menu_factory, "/Statistics/Protocol Hierarchy",
2621                          have_captured_packets);
2622
2623     walk_menu_tree_for_captured_packets(tap_menu_tree_root,
2624                                         have_captured_packets);
2625     set_toolbar_for_captured_packets(have_captured_packets);
2626 }
2627
2628 /* Enable or disable menu items based on whether a packet is selected and,
2629    if so, on the properties of the packet. */
2630 static gboolean
2631 walk_menu_tree_for_selected_packet(GList *node, frame_data *fd,
2632     epan_dissect_t *edt)
2633 {
2634     gboolean is_enabled;
2635     GList *child;
2636     menu_item_t *node_data = node->data;
2637
2638     /*
2639      * Is this a leaf node or an interior node?
2640      */
2641     if (node_data->children == NULL) {
2642         /*
2643          * It's a leaf node.
2644          *
2645          * If it has no "selected_packet_enabled()" routine,
2646          * leave its enabled/disabled status alone - it
2647          * doesn't depend on whether we have a packet selected
2648          * or not or on the selected packet.
2649          *
2650          * If it has a "selected_packet_enabled()" routine,
2651          * call it and set the item's enabled/disabled status
2652          * based on its return value.
2653          */
2654         if (node_data->selected_packet_enabled != NULL)
2655             node_data->enabled = node_data->selected_packet_enabled(fd, edt, node_data->callback_data);
2656     } else {
2657         /*
2658          * It's an interior node; call
2659          * "walk_menu_tree_for_selected_packet()" on all its
2660          * children and, if any of them are enabled, enable
2661          * this node, otherwise disable it.
2662          *
2663          * XXX - should we just leave all interior nodes enabled?
2664          * Which is a better UI choice?
2665          */
2666         is_enabled = FALSE;
2667         for (child = node_data->children; child != NULL; child =
2668                  child->next) {
2669             if (walk_menu_tree_for_selected_packet(child, fd, edt))
2670                 is_enabled = TRUE;
2671         }
2672         node_data->enabled = is_enabled;
2673     }
2674
2675     /*
2676      * The root node doesn't correspond to a menu tree item; it
2677      * has a null name pointer.
2678      */
2679     if (node_data->name != NULL) {
2680         set_menu_sensitivity(main_menu_factory, node_data->name,
2681                              node_data->enabled);
2682     }
2683     return node_data->enabled;
2684 }
2685
2686 gboolean
2687 packet_is_ssl(epan_dissect_t* edt)
2688 {
2689     GPtrArray* array;
2690     int ssl_id;
2691     gboolean is_ssl;
2692
2693     if (!edt || !edt->tree)
2694         return FALSE;
2695     ssl_id = proto_get_id_by_filter_name("ssl");
2696     if (ssl_id < 0)
2697         return FALSE;
2698     array = proto_find_finfo(edt->tree, ssl_id);
2699     is_ssl = (array->len > 0) ? TRUE : FALSE;
2700     g_ptr_array_free(array, TRUE);
2701     return is_ssl;
2702 }
2703
2704 void
2705 set_menus_for_selected_packet(capture_file *cf)
2706 {
2707     gboolean is_ssl = packet_is_ssl(cf->edt);
2708     set_menu_sensitivity(main_menu_factory, "/Edit/Mark Packet (toggle)",
2709                          cf->current_frame != NULL);
2710     set_menu_sensitivity(packet_list_menu_factory, "/Mark Packet (toggle)",
2711                          cf->current_frame != NULL);
2712     set_menu_sensitivity(main_menu_factory, "/Edit/Find Next Mark",
2713                          cf->current_frame != NULL);
2714     set_menu_sensitivity(main_menu_factory, "/Edit/Find Previous Mark",
2715                          cf->current_frame != NULL);
2716     set_menu_sensitivity(main_menu_factory, "/Edit/Mark All Packets",
2717                          cf->current_frame != NULL);
2718     set_menu_sensitivity(main_menu_factory, "/Edit/Unmark All Packets",
2719                          cf->current_frame != NULL);
2720     set_menu_sensitivity(main_menu_factory, "/Edit/Set Time Reference (toggle)",
2721                          cf->current_frame != NULL);
2722     set_menu_sensitivity(packet_list_menu_factory, "/Set Time Reference (toggle)",
2723                          cf->current_frame != NULL);
2724     set_menu_sensitivity(main_menu_factory, "/Edit/Find Next Reference",
2725                          cf->current_frame != NULL);
2726     set_menu_sensitivity(main_menu_factory, "/Edit/Find Previous Reference",
2727                          cf->current_frame != NULL);
2728     set_menu_sensitivity(main_menu_factory, "/View/Resize All Columns",
2729                          cf->current_frame != NULL);
2730     set_menu_sensitivity(main_menu_factory, "/View/Collapse All",
2731                          cf->current_frame != NULL);
2732     set_menu_sensitivity(tree_view_menu_factory, "/Collapse All",
2733                          cf->current_frame != NULL);
2734     set_menu_sensitivity(main_menu_factory, "/View/Expand All",
2735                          cf->current_frame != NULL);
2736     set_menu_sensitivity(tree_view_menu_factory, "/Expand All",
2737                          cf->current_frame != NULL);
2738     set_menu_sensitivity(main_menu_factory, "/View/Colorize Conversation",
2739                          cf->current_frame != NULL);
2740     set_menu_sensitivity(main_menu_factory, "/View/Reset Coloring 1-10",
2741                          tmp_color_filters_used());
2742     set_menu_sensitivity(main_menu_factory, "/View/Show Packet in New Window",
2743                          cf->current_frame != NULL);
2744     set_menu_sensitivity(packet_list_menu_factory, "/Show Packet in New Window",
2745                          cf->current_frame != NULL);
2746     set_menu_sensitivity(packet_list_menu_factory, "/SCTP",
2747                          cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_SCTP) : FALSE);
2748     set_menu_sensitivity(main_menu_factory, "/Analyze/Follow TCP Stream",
2749                          cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_TCP) : FALSE);
2750     set_menu_sensitivity(packet_list_menu_factory, "/Follow TCP Stream",
2751                          cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_TCP) : FALSE);
2752     set_menu_sensitivity(tree_view_menu_factory, "/Follow TCP Stream",
2753                          cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_TCP) : FALSE);
2754     set_menu_sensitivity(main_menu_factory, "/Analyze/Follow UDP Stream",
2755                          cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_UDP) : FALSE);
2756     set_menu_sensitivity(packet_list_menu_factory, "/Follow UDP Stream",
2757                          cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_UDP) : FALSE);
2758     set_menu_sensitivity(tree_view_menu_factory, "/Follow UDP Stream",
2759                          cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_UDP) : FALSE);
2760     set_menu_sensitivity(main_menu_factory, "/Analyze/Follow SSL Stream",
2761                          cf->current_frame != NULL ? is_ssl : FALSE);
2762     set_menu_sensitivity(packet_list_menu_factory, "/Follow SSL Stream",
2763                          cf->current_frame != NULL ? is_ssl : FALSE);
2764     set_menu_sensitivity(tree_view_menu_factory, "/Follow SSL Stream",
2765                          cf->current_frame != NULL ? is_ssl : FALSE);
2766     set_menu_sensitivity(packet_list_menu_factory, "/Conversation Filter",
2767                          cf->current_frame != NULL);
2768     set_menu_sensitivity(packet_list_menu_factory, "/Conversation Filter/Ethernet",
2769                          cf->current_frame != NULL ? (cf->edt->pi.dl_src.type == AT_ETHER) : FALSE);
2770     set_menu_sensitivity(packet_list_menu_factory, "/Conversation Filter/IP",
2771                          cf->current_frame != NULL ? ((cf->edt->pi.ethertype == ETHERTYPE_IP)||(cf->edt->pi.ethertype == ETHERTYPE_IPv6)) : FALSE);
2772     set_menu_sensitivity(packet_list_menu_factory, "/Conversation Filter/TCP",
2773                          cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_TCP) : FALSE);
2774     set_menu_sensitivity(packet_list_menu_factory, "/Conversation Filter/UDP",
2775                          cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_UDP) : FALSE);
2776     set_menu_sensitivity(packet_list_menu_factory, "/Conversation Filter/PN-CBA Server",
2777                          cf->current_frame != NULL ? (cf->edt->pi.profinet_type != 0 && cf->edt->pi.profinet_type < 10) : FALSE);
2778     set_menu_sensitivity(packet_list_menu_factory, "/Colorize Conversation",
2779                          cf->current_frame != NULL);
2780     set_menu_sensitivity(packet_list_menu_factory, "/Colorize Conversation/Ethernet",
2781                          cf->current_frame != NULL ? (cf->edt->pi.dl_src.type == AT_ETHER) : FALSE);
2782     set_menu_sensitivity(packet_list_menu_factory, "/Colorize Conversation/IP",
2783                          cf->current_frame != NULL ? ((cf->edt->pi.ethertype == ETHERTYPE_IP)||(cf->edt->pi.ethertype == ETHERTYPE_IPv6)) : FALSE);
2784     set_menu_sensitivity(packet_list_menu_factory, "/Colorize Conversation/TCP",
2785                          cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_TCP) : FALSE);
2786     set_menu_sensitivity(packet_list_menu_factory, "/Colorize Conversation/UDP",
2787                          cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_UDP) : FALSE);
2788     set_menu_sensitivity(packet_list_menu_factory, "/Colorize Conversation/PN-CBA Server",
2789                          cf->current_frame != NULL ? (cf->edt->pi.profinet_type != 0 && cf->edt->pi.profinet_type < 10) : FALSE);
2790     set_menu_sensitivity(main_menu_factory, "/Analyze/Decode As...",
2791                          cf->current_frame != NULL && decode_as_ok());
2792     set_menu_sensitivity(packet_list_menu_factory, "/Decode As...",
2793                          cf->current_frame != NULL && decode_as_ok());
2794     set_menu_sensitivity(tree_view_menu_factory, "/Decode As...",
2795                          cf->current_frame != NULL && decode_as_ok());
2796     set_menu_sensitivity(main_menu_factory, "/View/Name Resolution/Resolve Name",
2797                          cf->current_frame != NULL && (g_resolv_flags & RESOLV_ALL_ADDRS) != RESOLV_ALL_ADDRS);
2798     set_menu_sensitivity(tree_view_menu_factory, "/Resolve Name",
2799                          cf->current_frame != NULL && (g_resolv_flags & RESOLV_ALL_ADDRS) != RESOLV_ALL_ADDRS);
2800     set_menu_sensitivity(packet_list_menu_factory, "/Copy",
2801                          cf->current_frame != NULL);
2802     set_menu_sensitivity(packet_list_menu_factory, "/Apply as Filter",
2803                          cf->current_frame != NULL);
2804     set_menu_sensitivity(packet_list_menu_factory, "/Prepare a Filter",
2805                          cf->current_frame != NULL);
2806     set_menu_sensitivity(main_menu_factory, "/Tools/Firewall ACL Rules",
2807                          cf->current_frame != NULL);
2808
2809     walk_menu_tree_for_selected_packet(tap_menu_tree_root, cf->current_frame,
2810                                        cf->edt);
2811 }
2812
2813 /* Enable or disable menu items based on whether a tree row is selected
2814    and, if so, on the properties of the tree row. */
2815 static gboolean
2816 walk_menu_tree_for_selected_tree_row(GList *node, field_info *fi)
2817 {
2818     gboolean is_enabled;
2819     GList *child;
2820     menu_item_t *node_data = node->data;
2821
2822     /*
2823      * Is this a leaf node or an interior node?
2824      */
2825     if (node_data->children == NULL) {
2826         /*
2827          * It's a leaf node.
2828          *
2829          * If it has no "selected_tree_row_enabled()" routine,
2830          * leave its enabled/disabled status alone - it
2831          * doesn't depend on whether we have a tree row selected
2832          * or not or on the selected tree row.
2833          *
2834          * If it has a "selected_tree_row_enabled()" routine,
2835          * call it and set the item's enabled/disabled status
2836          * based on its return value.
2837          */
2838         if (node_data->selected_tree_row_enabled != NULL)
2839             node_data->enabled = node_data->selected_tree_row_enabled(fi, node_data->callback_data);
2840     } else {
2841         /*
2842          * It's an interior node; call
2843          * "walk_menu_tree_for_selected_tree_row()" on all its
2844          * children and, if any of them are enabled, enable
2845          * this node, otherwise disable it.
2846          *
2847          * XXX - should we just leave all interior nodes enabled?
2848          * Which is a better UI choice?
2849          */
2850         is_enabled = FALSE;
2851         for (child = node_data->children; child != NULL; child =
2852                  child->next) {
2853             if (walk_menu_tree_for_selected_tree_row(child, fi))
2854                 is_enabled = TRUE;
2855         }
2856         node_data->enabled = is_enabled;
2857     }
2858
2859     /*
2860      * The root node doesn't correspond to a menu tree item; it
2861      * has a null name pointer.
2862      */
2863     if (node_data->name != NULL) {
2864         set_menu_sensitivity(main_menu_factory, node_data->name,
2865                              node_data->enabled);
2866     }
2867     return node_data->enabled;
2868 }
2869
2870 static void
2871 menu_prefs_toggle_bool (GtkWidget *w, gpointer data)
2872 {
2873     gboolean *value = data;
2874     module_t *module = g_object_get_data (G_OBJECT(w), "module");
2875
2876     module->prefs_changed = TRUE;
2877     *value = !(*value);
2878
2879     prefs_apply (module);
2880     if (!prefs.gui_use_pref_save) {
2881         prefs_main_write();
2882     }
2883     redissect_packets();
2884 }
2885
2886 static void
2887 menu_prefs_change_enum (GtkWidget *w, gpointer data)
2888 {
2889     gint *value = data;
2890     module_t *module = g_object_get_data (G_OBJECT(w), "module");
2891     gint new_value = GPOINTER_TO_INT(g_object_get_data (G_OBJECT(w), "enumval"));
2892
2893     if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM(w)))
2894         return;
2895
2896     if (*value != new_value) {
2897         module->prefs_changed = TRUE;
2898         *value = new_value;
2899
2900         prefs_apply (module);
2901         if (!prefs.gui_use_pref_save) {
2902             prefs_main_write();
2903         }
2904         redissect_packets();
2905     }
2906 }
2907
2908 void
2909 menu_prefs_reset(void)
2910 {
2911         g_free (g_object_get_data(G_OBJECT(tree_view_menu_factory), "menu_abbrev"));
2912         g_object_set_data(G_OBJECT(tree_view_menu_factory), "menu_abbrev", NULL);
2913 }
2914
2915 static void
2916 menu_prefs_change_ok (GtkWidget *w, gpointer parent_w)
2917 {
2918     GtkWidget *entry = g_object_get_data (G_OBJECT(w), "entry");
2919     module_t *module = g_object_get_data (G_OBJECT(w), "module");
2920     pref_t *pref = g_object_get_data (G_OBJECT(w), "pref");
2921     const gchar *new_value =  gtk_entry_get_text(GTK_ENTRY(entry));
2922     range_t *newrange;
2923     gchar *p;
2924     guint uval;
2925
2926     switch (pref->type) {
2927     case PREF_UINT:
2928         uval = strtoul(new_value, &p, pref->info.base);
2929         if (p == new_value || *p != '\0') {
2930             simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2931                           "The value \"%s\" isn't a valid number.",
2932                           new_value);
2933             return;
2934         }
2935         if (*pref->varp.uint != uval) {
2936             module->prefs_changed = TRUE;
2937             *pref->varp.uint = uval;
2938         }
2939         break;
2940     case PREF_STRING:
2941         if (strcmp (*pref->varp.string, new_value) != 0) {
2942             module->prefs_changed = TRUE;
2943             g_free((void*)*pref->varp.string);
2944             *pref->varp.string = g_strdup(new_value);
2945         }
2946         break;
2947     case PREF_RANGE:
2948         if (range_convert_str(&newrange, new_value, pref->info.max_value) != CVT_NO_ERROR) {
2949             simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2950                           "The value \"%s\" isn't a valid range.",
2951                           new_value);
2952             return;
2953         }
2954         if (!ranges_are_equal(*pref->varp.range, newrange)) {
2955             module->prefs_changed = TRUE;
2956             g_free(*pref->varp.range);
2957             *pref->varp.range = newrange;
2958         } else {
2959             g_free (newrange);
2960         }
2961         break;
2962     default:
2963         g_assert_not_reached();
2964         break;
2965     }
2966
2967     if (module->prefs_changed) {
2968         /* Ensure we reload the sub menu */
2969         menu_prefs_reset();
2970         prefs_apply (module);
2971         if (!prefs.gui_use_pref_save) {
2972             prefs_main_write();
2973         }
2974         redissect_packets();
2975     }
2976
2977     window_destroy(GTK_WIDGET(parent_w));
2978 }
2979
2980 static void
2981 menu_prefs_change_cancel (GtkWidget *w _U_, gpointer parent_w)
2982 {
2983     window_destroy(GTK_WIDGET(parent_w));
2984 }
2985
2986 static void 
2987 menu_prefs_edit_dlg (GtkWidget *w, gpointer data)
2988 {
2989     pref_t *pref = data;
2990     module_t *module = g_object_get_data (G_OBJECT(w), "module");
2991     gchar *value = NULL;
2992
2993     GtkWidget *win, *main_tb, *main_vb, *bbox, *cancel_bt, *ok_bt;
2994     GtkWidget *entry, *label;
2995     GtkTooltips *tooltips;
2996
2997     switch (pref->type) {
2998     case PREF_UINT:
2999         switch (pref->info.base) {
3000         case 8:
3001             value = g_strdup_printf("%o", *pref->varp.uint);
3002             break;
3003         case 10:
3004             value = g_strdup_printf("%u", *pref->varp.uint);
3005             break;
3006         case 16:
3007             value = g_strdup_printf("%x", *pref->varp.uint);
3008             break;
3009         default:
3010             g_assert_not_reached();
3011             break;
3012         }
3013         break;
3014     case PREF_STRING:
3015         value = g_strdup(*pref->varp.string);
3016         break;
3017     case PREF_RANGE:
3018         value = g_strdup(range_convert_range (*pref->varp.range));
3019         break;
3020     default:
3021         g_assert_not_reached();
3022         break;
3023     }
3024
3025     tooltips = gtk_tooltips_new();
3026
3027     win = dlg_window_new(module->description);
3028
3029     gtk_window_set_resizable(GTK_WINDOW(win),FALSE);
3030     gtk_window_resize(GTK_WINDOW(win), 400, 100);
3031
3032     main_vb = gtk_vbox_new(FALSE, 5);
3033     gtk_container_add(GTK_CONTAINER(win), main_vb);
3034     gtk_container_set_border_width(GTK_CONTAINER(main_vb), 6);
3035
3036     main_tb = gtk_table_new(2, 2, FALSE);
3037     gtk_box_pack_start(GTK_BOX(main_vb), main_tb, FALSE, FALSE, 0);
3038     gtk_table_set_col_spacings(GTK_TABLE(main_tb), 10);
3039
3040     label = gtk_label_new(ep_strdup_printf("%s:", pref->title));
3041     gtk_table_attach_defaults(GTK_TABLE(main_tb), label, 0, 1, 1, 2);
3042     gtk_misc_set_alignment(GTK_MISC(label), 1.0f, 0.5f);
3043     if (pref->description)
3044         gtk_tooltips_set_tip(tooltips, label, pref->description, NULL);
3045
3046     entry = gtk_entry_new();
3047     gtk_table_attach_defaults(GTK_TABLE(main_tb), entry, 1, 2, 1, 2);
3048     gtk_entry_set_text(GTK_ENTRY(entry), value);
3049     if (pref->description)
3050         gtk_tooltips_set_tip(tooltips, entry, pref->description, NULL);
3051
3052     bbox = dlg_button_row_new(GTK_STOCK_CANCEL,GTK_STOCK_OK, NULL);
3053     gtk_box_pack_end(GTK_BOX(main_vb), bbox, FALSE, FALSE, 0);
3054
3055     ok_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_OK);
3056     g_object_set_data (G_OBJECT(ok_bt), "module", module);
3057     g_object_set_data (G_OBJECT(ok_bt), "entry", entry);
3058     g_object_set_data (G_OBJECT(ok_bt), "pref", pref);
3059     g_signal_connect(ok_bt, "clicked", G_CALLBACK(menu_prefs_change_ok), win);
3060
3061     dlg_set_activate(entry, ok_bt);
3062
3063     cancel_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CANCEL);
3064     g_signal_connect(cancel_bt, "clicked", G_CALLBACK(menu_prefs_change_cancel), win);
3065     window_set_cancel_button(win, cancel_bt, NULL);
3066
3067     gtk_widget_grab_default(ok_bt);
3068     gtk_widget_show_all(win);
3069     g_free(value);
3070 }
3071
3072 static guint
3073 add_protocol_prefs_menu (pref_t *pref, gpointer data)
3074 {
3075     GtkWidget *menu_preferences;
3076     GtkWidget *menu_item, *menu_sub_item, *sub_menu;
3077     GSList *group = NULL;
3078     module_t *module = data;
3079     const enum_val_t *enum_valp;
3080     gchar *label = NULL;
3081
3082     switch (pref->type) {
3083     case PREF_UINT:
3084         switch (pref->info.base) {
3085         case 8:
3086             label = g_strdup_printf ("%s: %o", pref->title, *pref->varp.uint);
3087             break;
3088         case 10:
3089             label = g_strdup_printf ("%s: %u", pref->title, *pref->varp.uint);
3090             break;
3091         case 16:
3092             label = g_strdup_printf ("%s: %x", pref->title, *pref->varp.uint);
3093             break;
3094         default:
3095             g_assert_not_reached();
3096             break;
3097         }
3098         menu_item = gtk_menu_item_new_with_label(label);
3099         g_object_set_data (G_OBJECT(menu_item), "module", module);
3100         g_signal_connect(menu_item, "activate", G_CALLBACK(menu_prefs_edit_dlg), pref);
3101         g_free (label);
3102         break;
3103     case PREF_BOOL:
3104         menu_item = gtk_check_menu_item_new_with_label(pref->title);
3105         gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(menu_item), *pref->varp.boolp);
3106         g_object_set_data (G_OBJECT(menu_item), "module", module);
3107         g_signal_connect(menu_item, "activate", G_CALLBACK(menu_prefs_toggle_bool), pref->varp.boolp);
3108         break;
3109     case PREF_ENUM:
3110         menu_item = gtk_menu_item_new_with_label(pref->title);
3111         sub_menu = gtk_menu_new();
3112         gtk_menu_item_set_submenu (GTK_MENU_ITEM(menu_item), sub_menu);
3113         enum_valp = pref->info.enum_info.enumvals;
3114         while (enum_valp->name != NULL) {
3115             menu_sub_item = gtk_radio_menu_item_new_with_label(group, enum_valp->description);
3116             group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (menu_sub_item));
3117             if (enum_valp->value == *pref->varp.enump) {
3118                 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(menu_sub_item), TRUE);
3119             }
3120             g_object_set_data (G_OBJECT(menu_sub_item), "module", module);
3121             g_object_set_data (G_OBJECT(menu_sub_item), "enumval", GINT_TO_POINTER(enum_valp->value));
3122             g_signal_connect(menu_sub_item, "activate", G_CALLBACK(menu_prefs_change_enum), pref->varp.enump);
3123             gtk_menu_shell_append (GTK_MENU_SHELL(sub_menu), menu_sub_item);
3124             gtk_widget_show (menu_sub_item);
3125             enum_valp++;
3126         }
3127         break;
3128     case PREF_STRING:
3129         label = g_strdup_printf ("%s: %s", pref->title, *pref->varp.string);
3130         menu_item = gtk_menu_item_new_with_label(label);
3131         g_object_set_data (G_OBJECT(menu_item), "module", module);
3132         g_signal_connect(menu_item, "activate", G_CALLBACK(menu_prefs_edit_dlg), pref);
3133         g_free (label);
3134         break;
3135     case PREF_RANGE:
3136         label = g_strdup_printf ("%s: %s", pref->title, range_convert_range (*pref->varp.range));
3137         menu_item = gtk_menu_item_new_with_label(label);
3138         g_object_set_data (G_OBJECT(menu_item), "module", module);
3139         g_signal_connect(menu_item, "activate", G_CALLBACK(menu_prefs_edit_dlg), pref);
3140         g_free (label);
3141         break;
3142     case PREF_UAT:
3143         label = g_strdup_printf ("%s...", pref->title);
3144         menu_item = gtk_menu_item_new_with_label(label);
3145         g_signal_connect (menu_item, "activate", G_CALLBACK(uat_window_cb), pref->varp.uat);
3146         g_free (label);
3147         break;
3148     case PREF_STATIC_TEXT:
3149     case PREF_OBSOLETE:
3150     default:
3151         /* Nothing to add */
3152         return 0;
3153     }
3154
3155     menu_preferences = gtk_item_factory_get_widget(tree_view_menu_factory, "/Protocol Preferences");
3156     sub_menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM(menu_preferences));
3157     gtk_menu_shell_append (GTK_MENU_SHELL(sub_menu), menu_item);
3158     gtk_widget_show (menu_item);
3159
3160     return 0;
3161 }
3162
3163 static void
3164 rebuild_protocol_prefs_menu (module_t *prefs, gboolean preferences)
3165 {
3166     GtkWidget *menu_preferences, *menu_item;
3167     GtkWidget *sub_menu;
3168     gchar *label;
3169
3170     menu_preferences = gtk_item_factory_get_widget(tree_view_menu_factory, "/Protocol Preferences");
3171
3172     if (preferences) {
3173         sub_menu = gtk_menu_new();
3174         gtk_menu_item_set_submenu (GTK_MENU_ITEM(menu_preferences), sub_menu);
3175
3176         label = g_strdup_printf ("%s Preferences...", prefs->description);
3177         menu_item = gtk_image_menu_item_new_with_label (label);
3178         gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM(menu_item), 
3179                                        gtk_image_new_from_stock(GTK_STOCK_PREFERENCES, GTK_ICON_SIZE_MENU));
3180         gtk_menu_shell_append (GTK_MENU_SHELL(sub_menu), menu_item);
3181         g_signal_connect_swapped(GTK_OBJECT(menu_item), "activate",
3182                                  G_CALLBACK(properties_cb), (GtkObject *) menu_item);
3183         gtk_widget_show (menu_item);
3184         g_free (label);
3185
3186         menu_item = gtk_menu_item_new();
3187         gtk_menu_shell_append (GTK_MENU_SHELL(sub_menu), menu_item);
3188         gtk_widget_show (menu_item);
3189
3190         prefs_pref_foreach(prefs, add_protocol_prefs_menu, prefs);
3191     } else {
3192         /* No preferences, remove sub menu */
3193         gtk_menu_item_set_submenu (GTK_MENU_ITEM(menu_preferences), NULL);
3194     }
3195
3196 }
3197
3198 void
3199 menus_set_column_align_default (gboolean right_justify)
3200 {
3201     GtkWidget   *submenu, *menu_item_child;
3202     GList       *child_list, *child_list_item;
3203     const gchar *menu_item_name;
3204     size_t       menu_item_len;
3205     
3206     /* get the submenu container item */
3207     submenu = packet_list_heading_factory->widget;
3208
3209     /* find the corresponding menu items to update */
3210     child_list = gtk_container_get_children(GTK_CONTAINER(submenu));
3211     child_list_item = child_list;
3212     while(child_list_item) {
3213         menu_item_child = (GTK_BIN(child_list_item->data))->child;
3214         if (menu_item_child != NULL) {
3215             menu_item_name = gtk_label_get_text(GTK_LABEL(menu_item_child));
3216             menu_item_len = strlen (menu_item_name);
3217             if(strncmp(menu_item_name, "Align Left", 10) == 0) {
3218                 if (!right_justify && menu_item_len == 10) {
3219                     gtk_label_set_text(GTK_LABEL(menu_item_child), "Align Left\t(default)");
3220                 } else if (right_justify && menu_item_len > 10) {
3221                     gtk_label_set_text(GTK_LABEL(menu_item_child), "Align Left");
3222                 }
3223             } else if (strncmp (menu_item_name, "Align Right", 11) == 0) {
3224                 if (right_justify && menu_item_len == 11) {
3225                     gtk_label_set_text(GTK_LABEL(menu_item_child), "Align Right\t(default)");
3226                 } else if (!right_justify && menu_item_len > 11) {
3227                     gtk_label_set_text(GTK_LABEL(menu_item_child), "Align Right");
3228                 }
3229             }
3230         }
3231         child_list_item = g_list_next(child_list_item);
3232     }
3233     g_list_free(child_list);
3234 }
3235
3236 void
3237 set_menus_for_selected_tree_row(capture_file *cf)
3238 {
3239     gboolean properties;
3240     gint id;
3241
3242     if (cf->finfo_selected != NULL) {
3243         header_field_info *hfinfo = cf->finfo_selected->hfinfo;
3244         const char *abbrev;
3245         char *prev_abbrev;
3246
3247         if (hfinfo->parent == -1) {
3248             abbrev = hfinfo->abbrev;
3249             id = (hfinfo->type == FT_PROTOCOL) ? proto_get_id((protocol_t *)hfinfo->strings) : -1;
3250         } else {
3251             abbrev = proto_registrar_get_abbrev(hfinfo->parent);
3252             id = hfinfo->parent;
3253         }
3254         properties = prefs_is_registered_protocol(abbrev);
3255
3256         set_menu_sensitivity(main_menu_factory,
3257                              "/File/Export/Selected Packet Bytes...", TRUE);
3258         set_menu_sensitivity(main_menu_factory,
3259                              "/Go/Go to Corresponding Packet", hfinfo->type == FT_FRAMENUM);
3260         set_menu_sensitivity(tree_view_menu_factory,
3261                              "/Go to Corresponding Packet", hfinfo->type == FT_FRAMENUM);
3262         set_menu_sensitivity(main_menu_factory, "/Edit/Copy/Description",
3263                              proto_can_match_selected(cf->finfo_selected, cf->edt));
3264         set_menu_sensitivity(main_menu_factory, "/Edit/Copy/Fieldname",
3265                              proto_can_match_selected(cf->finfo_selected, cf->edt));
3266         set_menu_sensitivity(main_menu_factory, "/Edit/Copy/Value",
3267                              proto_can_match_selected(cf->finfo_selected, cf->edt));
3268         set_menu_sensitivity(main_menu_factory, "/Edit/Copy/As Filter",
3269                              proto_can_match_selected(cf->finfo_selected, cf->edt));
3270         set_menu_sensitivity(tree_view_menu_factory, "/Copy",
3271                              TRUE);
3272         set_menu_sensitivity(tree_view_menu_factory, "/Copy/As Filter",
3273                              proto_can_match_selected(cf->finfo_selected, cf->edt));
3274         set_menu_sensitivity(main_menu_factory, "/Analyze/Apply as Column",
3275                              hfinfo->type != FT_NONE);
3276         set_menu_sensitivity(main_menu_factory, "/Analyze/Apply as Filter",
3277                              proto_can_match_selected(cf->finfo_selected, cf->edt));
3278         set_menu_sensitivity(tree_view_menu_factory, "/Apply as Column",
3279                              hfinfo->type != FT_NONE);
3280         set_menu_sensitivity(tree_view_menu_factory, "/Apply as Filter",
3281                              proto_can_match_selected(cf->finfo_selected, cf->edt));
3282         set_menu_sensitivity(main_menu_factory, "/Analyze/Prepare a Filter",
3283                              proto_can_match_selected(cf->finfo_selected, cf->edt));
3284         set_menu_sensitivity(tree_view_menu_factory, "/Prepare a Filter",
3285                              proto_can_match_selected(cf->finfo_selected, cf->edt));
3286         set_menu_sensitivity(tree_view_menu_factory, "/Colorize with Filter",
3287                              proto_can_match_selected(cf->finfo_selected, cf->edt));
3288         set_menu_sensitivity(tree_view_menu_factory, "/Protocol Preferences",
3289                              properties);
3290         set_menu_sensitivity(tree_view_menu_factory, "/Disable Protocol...",
3291                              (id == -1) ? FALSE : proto_can_toggle_protocol(id));
3292         set_menu_sensitivity(main_menu_factory, "/View/Expand Subtrees", cf->finfo_selected->tree_type != -1);
3293         set_menu_sensitivity(tree_view_menu_factory, "/Expand Subtrees", cf->finfo_selected->tree_type != -1);
3294         set_menu_sensitivity(tree_view_menu_factory, "/Wiki Protocol Page",
3295                              TRUE);
3296         set_menu_sensitivity(tree_view_menu_factory, "/Filter Field Reference",
3297                              TRUE);
3298         
3299         prev_abbrev = g_object_get_data(G_OBJECT(tree_view_menu_factory), "menu_abbrev");
3300         if (!prev_abbrev || (strcmp (prev_abbrev, abbrev) != 0)) {
3301             /* No previous protocol or protocol changed - update Protocol Preferences menu */
3302             module_t *prefs = prefs_find_module(abbrev);
3303             rebuild_protocol_prefs_menu (prefs, properties);
3304
3305             g_object_set_data(G_OBJECT(tree_view_menu_factory), "menu_abbrev", g_strdup(abbrev));
3306             g_free (prev_abbrev);
3307         }
3308     } else {
3309         set_menu_sensitivity(main_menu_factory,
3310                              "/File/Export/Selected Packet Bytes...", FALSE);
3311         set_menu_sensitivity(main_menu_factory,
3312                              "/Go/Go to Corresponding Packet", FALSE);
3313         set_menu_sensitivity(tree_view_menu_factory,
3314                              "/Go to Corresponding Packet", FALSE);
3315         set_menu_sensitivity(main_menu_factory, "/Edit/Copy/Description", FALSE);
3316         set_menu_sensitivity(main_menu_factory, "/Edit/Copy/Fieldname", FALSE);
3317         set_menu_sensitivity(main_menu_factory, "/Edit/Copy/Value", FALSE);
3318         set_menu_sensitivity(main_menu_factory, "/Edit/Copy/As Filter", FALSE);
3319         set_menu_sensitivity(tree_view_menu_factory, "/Copy", FALSE);
3320         set_menu_sensitivity(main_menu_factory, "/Analyze/Apply as Column", FALSE);
3321         set_menu_sensitivity(tree_view_menu_factory, "/Apply as Column", FALSE);
3322         set_menu_sensitivity(main_menu_factory, "/Analyze/Apply as Filter", FALSE);
3323         set_menu_sensitivity(tree_view_menu_factory, "/Apply as Filter", FALSE);
3324         set_menu_sensitivity(main_menu_factory, "/Analyze/Prepare a Filter", FALSE);
3325         set_menu_sensitivity(tree_view_menu_factory, "/Prepare a Filter", FALSE);
3326         set_menu_sensitivity(tree_view_menu_factory, "/Colorize with Filter", FALSE);
3327         set_menu_sensitivity(tree_view_menu_factory, "/Protocol Preferences",
3328                              FALSE);
3329         set_menu_sensitivity(tree_view_menu_factory, "/Disable Protocol...", FALSE);
3330         set_menu_sensitivity(main_menu_factory, "/View/Expand Subtrees", FALSE);
3331         set_menu_sensitivity(tree_view_menu_factory, "/Expand Subtrees", FALSE);
3332         set_menu_sensitivity(tree_view_menu_factory, "/Wiki Protocol Page",
3333                              FALSE);
3334         set_menu_sensitivity(tree_view_menu_factory, "/Filter Field Reference",
3335                              FALSE);
3336     }
3337
3338     walk_menu_tree_for_selected_tree_row(tap_menu_tree_root, cf->finfo_selected);
3339 }
3340
3341 void set_menus_for_packet_history(gboolean back_history, gboolean forward_history) {
3342
3343     set_menu_sensitivity(main_menu_factory, "/Go/Back", back_history);
3344     set_menu_sensitivity(main_menu_factory, "/Go/Forward", forward_history);
3345
3346     set_toolbar_for_packet_history(back_history, forward_history);
3347 }
3348
3349
3350 void set_menus_for_file_set(gboolean file_set, gboolean previous_file, gboolean next_file) {
3351
3352     set_menu_sensitivity(main_menu_factory, "/File/File Set/List Files", file_set);
3353     set_menu_sensitivity(main_menu_factory, "/File/File Set/Previous File", previous_file);
3354     set_menu_sensitivity(main_menu_factory, "/File/File Set/Next File", next_file);
3355 }
3356
3357 /*
3358  * Editor modelines
3359  *
3360  * Local Variables:
3361  * c-basic-offset: 4
3362  * tab-width: 8
3363  * indent-tabs-mode: nil
3364  * End:
3365  *
3366  * ex: set shiftwidth=4 tabstop=8 expandtab
3367  * :indentSize=4:tabSize=8:noTabs=true:
3368  */
3369