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