6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@ethereal.com>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
35 #include "../stat_menu.h"
36 #include "gui_stat_menu.h"
37 #include <epan/packet.h>
38 #include <epan/addr_resolv.h>
39 #include <epan/prefs.h>
41 #include <epan/timestamp.h>
42 #include <epan/ipproto.h>
44 #include "about_dlg.h"
45 #include "capture_dlg.h"
46 #include "color_dlg.h"
47 #include "filter_dlg.h"
48 #include "dlg_utils.h"
49 #include "capture_file_dlg.h"
50 #include "fileset_dlg.h"
53 #include "summary_dlg.h"
54 #include "prefs_dlg.h"
55 #include "packet_win.h"
57 #include "follow_dlg.h"
58 #include "decode_as_dlg.h"
60 #include "supported_protos_dlg.h"
61 #include "proto_dlg.h"
62 #include "proto_hier_stats_dlg.h"
64 #include <epan/plugins.h>
65 #include <epan/epan_dissect.h>
66 #include "compat_macros.h"
68 #include "gtkglobals.h"
71 #include "packet_list.h"
74 #include "../ui_util.h"
75 #include "proto_draw.h"
76 #include "conversations_table.h"
77 #include "hostlist_table.h"
78 #include "simple_dialog.h"
79 #include "packet_history.h"
80 #include "color_filters.h"
83 GtkWidget *popup_menu_object;
86 clear_menu_recent_capture_file_cmd_cb(GtkWidget *w, gpointer unused _U_);
88 typedef struct _menu_item {
92 GtkItemFactoryCallback callback;
93 gpointer callback_data;
94 gboolean (*selected_packet_enabled)(frame_data *, epan_dissect_t *);
95 gboolean (*selected_tree_row_enabled)(field_info *);
99 static GList *tap_menu_tree_root = NULL;
102 merge_all_tap_menus(GList *node);
104 #define GTK_MENU_FUNC(a) ((GtkItemFactoryCallback)(a))
106 static void menus_init(void);
107 static void set_menu_sensitivity (GtkItemFactory *, const gchar *, gint);
108 static void main_toolbar_show_cb(GtkWidget *w _U_, gpointer d _U_);
109 static void filter_toolbar_show_cb(GtkWidget *w _U_, gpointer d _U_);
110 static void packet_list_show_cb(GtkWidget *w _U_, gpointer d _U_);
111 static void tree_view_show_cb(GtkWidget *w _U_, gpointer d _U_);
112 static void byte_view_show_cb(GtkWidget *w _U_, gpointer d _U_);
113 static void statusbar_show_cb(GtkWidget *w _U_, gpointer d _U_);
114 static void timestamp_absolute_cb(GtkWidget *w _U_, gpointer d _U_);
115 static void timestamp_absolute_date_cb(GtkWidget *w _U_, gpointer d _U_);
116 static void timestamp_relative_cb(GtkWidget *w _U_, gpointer d _U_);
117 static void timestamp_delta_cb(GtkWidget *w _U_, gpointer d _U_);
118 static void timestamp_auto_cb(GtkWidget *w _U_, gpointer d _U_);
119 static void timestamp_sec_cb(GtkWidget *w _U_, gpointer d _U_);
120 static void timestamp_dsec_cb(GtkWidget *w _U_, gpointer d _U_);
121 static void timestamp_csec_cb(GtkWidget *w _U_, gpointer d _U_);
122 static void timestamp_msec_cb(GtkWidget *w _U_, gpointer d _U_);
123 static void timestamp_usec_cb(GtkWidget *w _U_, gpointer d _U_);
124 static void timestamp_nsec_cb(GtkWidget *w _U_, gpointer d _U_);
125 static void name_resolution_mac_cb(GtkWidget *w _U_, gpointer d _U_);
126 static void name_resolution_network_cb(GtkWidget *w _U_, gpointer d _U_);
127 static void name_resolution_transport_cb(GtkWidget *w _U_, gpointer d _U_);
129 static void auto_scroll_live_cb(GtkWidget *w _U_, gpointer d _U_);
131 static void colorize_cb(GtkWidget *w _U_, gpointer d _U_);
133 /* This is the GtkItemFactoryEntry structure used to generate new menus.
134 Item 1: The menu path. The letter after the underscore indicates an
135 accelerator key once the menu is open.
136 Item 2: The accelerator key for the entry
137 Item 3: The callback function.
138 Item 4: The callback action. This changes the parameters with
139 which the function is called. The default is 0.
140 Item 5: The item type, used to define what kind of an item it is.
141 Here are the possible values:
145 "<Title>" -> create a title item
146 "<Item>" -> create a simple item
147 "<ImageItem>" -> create an item holding an image (gtk2)
148 "<StockItem>" -> create an item holding a stock image (gtk2)
149 "<CheckItem>" -> create a check item
150 "<ToggleItem>" -> create a toggle item
151 "<RadioItem>" -> create a radio item
152 <path> -> path of a radio item to link against
153 "<Separator>" -> create a separator
154 "<Tearoff>" -> create a tearoff separator (gtk2)
155 "<Branch>" -> create an item to hold sub items (optional)
156 "<LastBranch>" -> create a right justified branch
157 Item 6: extra data needed for ImageItem and StockItem (gtk2)
160 /* As a general GUI guideline, we try to follow the Gnome Human Interface Guidelines, which can be found at:
161 http://developer.gnome.org/projects/gup/hig/1.0/index.html
163 Please note: there are some differences between the Gnome HIG menu suggestions and our implementation:
165 File/Open Recent: the Gnome HIG suggests putting the list of recently used files as elements into the File menuitem.
166 As this is ok for only a few items, this will become unhandy for 10 or even more list entries.
167 For this reason, we use a submenu for this.
169 File/Close: the Gnome HIG suggests putting this item just above the Quit item.
170 This results in unintuitive behaviour as both Close and Quit items are very near together.
171 By putting the Close item near the open item(s), it better suggests that it will close the
172 currently opened/captured file only.
176 static GtkItemFactoryEntry menu_items[] =
178 ITEM_FACTORY_ENTRY("/_File", NULL, NULL, 0, "<Branch>", NULL),
179 ITEM_FACTORY_STOCK_ENTRY("/File/_Open...", "<control>O", file_open_cmd_cb,
181 ITEM_FACTORY_ENTRY("/File/Open _Recent", NULL, NULL, 0, "<Branch>", NULL),
182 ITEM_FACTORY_ENTRY("/File/_Merge...", NULL, file_merge_cmd_cb, 0, NULL, NULL),
183 ITEM_FACTORY_STOCK_ENTRY("/File/_Close", "<control>W", file_close_cmd_cb,
185 ITEM_FACTORY_ENTRY("/File/<separator>", NULL, NULL, 0, "<Separator>", NULL),
186 ITEM_FACTORY_STOCK_ENTRY("/File/_Save", "<control>S", file_save_cmd_cb,
188 ITEM_FACTORY_STOCK_ENTRY("/File/Save _As...", "<shift><control>S", file_save_as_cmd_cb,
189 0, GTK_STOCK_SAVE_AS),
190 ITEM_FACTORY_ENTRY("/File/<separator>", NULL, NULL, 0, "<Separator>", NULL),
191 ITEM_FACTORY_ENTRY("/File/File Set", NULL, NULL, 0, "<Branch>", NULL),
192 ITEM_FACTORY_STOCK_ENTRY("/File/File Set/List Files", NULL, fileset_cb, 0, ETHEREAL_STOCK_FILE_SET_LIST),
193 ITEM_FACTORY_STOCK_ENTRY("/File/File Set/Next File", NULL, fileset_next_cb, 0, ETHEREAL_STOCK_FILE_SET_NEXT),
194 ITEM_FACTORY_STOCK_ENTRY("/File/File Set/Previous File", NULL, fileset_previous_cb, 0, ETHEREAL_STOCK_FILE_SET_PREVIOUS),
195 ITEM_FACTORY_ENTRY("/File/<separator>", NULL, NULL, 0, "<Separator>", NULL),
196 ITEM_FACTORY_ENTRY("/File/_Export", NULL, NULL, 0, "<Branch>", NULL),
197 ITEM_FACTORY_ENTRY("/File/Export/as \"Plain _Text\" file...", NULL, export_text_cmd_cb,
199 ITEM_FACTORY_ENTRY("/File/Export/as \"_PostScript\" file...", NULL, export_ps_cmd_cb,
201 ITEM_FACTORY_ENTRY("/File/Export/as \"_CSV\" (Comma Separated Values packet summary) file...",
202 NULL, export_csv_cmd_cb, 0, NULL, NULL),
203 ITEM_FACTORY_ENTRY("/File/Export/<separator>", NULL, NULL, 0, "<Separator>", NULL),
204 ITEM_FACTORY_ENTRY("/File/Export/as XML - \"P_SML\" (packet summary) file...", NULL, export_psml_cmd_cb,
206 ITEM_FACTORY_ENTRY("/File/Export/as XML - \"P_DML\" (packet details) file...", NULL, export_pdml_cmd_cb,
208 ITEM_FACTORY_ENTRY("/File/Export/<separator>", NULL, NULL, 0, "<Separator>", NULL),
209 ITEM_FACTORY_ENTRY("/File/Export/Selected Packet _Bytes...", "<control>H", savehex_cb,
211 ITEM_FACTORY_ENTRY("/File/<separator>", NULL, NULL, 0, "<Separator>", NULL),
212 ITEM_FACTORY_STOCK_ENTRY("/File/_Print...", "<control>P", file_print_cmd_cb,
214 ITEM_FACTORY_ENTRY("/File/<separator>", NULL, NULL, 0, "<Separator>", NULL),
215 ITEM_FACTORY_STOCK_ENTRY("/File/_Quit", "<control>Q", file_quit_cmd_cb,
217 ITEM_FACTORY_ENTRY("/_Edit", NULL, NULL, 0, "<Branch>", NULL),
219 /* Un-#if this when we actually implement Cut/Copy/Paste. */
220 ITEM_FACTORY_STOCK_ENTRY("/Edit/Cut", "<control>X", NULL,
222 ITEM_FACTORY_STOCK_ENTRY("/Edit/Copy", "<control>C", NULL,
224 ITEM_FACTORY_STOCK_ENTRY("/Edit/Paste", "<control>V", NULL,
226 ITEM_FACTORY_ENTRY("/Edit/<separator>", NULL, NULL, 0, "<Separator>"),
228 ITEM_FACTORY_STOCK_ENTRY("/Edit/_Find Packet...", "<control>F",
229 find_frame_cb, 0, GTK_STOCK_FIND),
230 ITEM_FACTORY_ENTRY("/Edit/Find Ne_xt", "<control>N", find_next_cb, 0, NULL, NULL),
231 ITEM_FACTORY_ENTRY("/Edit/Find Pre_vious", "<control>B", find_previous_cb, 0, NULL, NULL),
232 ITEM_FACTORY_ENTRY("/Edit/<separator>", NULL, NULL, 0, "<Separator>", NULL),
233 ITEM_FACTORY_ENTRY("/Edit/_Time Reference", NULL, NULL, 0, "<Branch>", NULL),
234 ITEM_FACTORY_STOCK_ENTRY("/Edit/Time Reference/Set Time Reference (toggle)", "<control>T", reftime_frame_cb,
235 REFTIME_TOGGLE, ETHEREAL_STOCK_TIME),
236 ITEM_FACTORY_ENTRY("/Edit/Time Reference/Find Next", NULL, reftime_frame_cb, REFTIME_FIND_NEXT, NULL, NULL),
237 ITEM_FACTORY_ENTRY("/Edit/Time Reference/Find Previous", NULL, reftime_frame_cb, REFTIME_FIND_PREV, NULL, NULL),
238 ITEM_FACTORY_ENTRY("/Edit/_Mark Packet (toggle)", "<control>M", packet_list_mark_frame_cb,
240 ITEM_FACTORY_ENTRY("/Edit/Mark _All Packets", NULL, packet_list_mark_all_frames_cb,
242 ITEM_FACTORY_ENTRY("/Edit/_Unmark All Packets", NULL, packet_list_unmark_all_frames_cb,
244 ITEM_FACTORY_ENTRY("/Edit/<separator>", NULL, NULL, 0, "<Separator>", NULL),
245 ITEM_FACTORY_STOCK_ENTRY("/Edit/_Preferences...", "<shift><control>P", prefs_cb,
246 0, GTK_STOCK_PREFERENCES),
247 ITEM_FACTORY_ENTRY("/_View", NULL, NULL, 0, "<Branch>", NULL),
248 ITEM_FACTORY_ENTRY("/View/_Main Toolbar", NULL, main_toolbar_show_cb, 0, "<CheckItem>", NULL),
249 ITEM_FACTORY_ENTRY("/View/_Filter Toolbar", NULL, filter_toolbar_show_cb, 0, "<CheckItem>", NULL),
250 ITEM_FACTORY_ENTRY("/View/_Statusbar", NULL, statusbar_show_cb, 0, "<CheckItem>", NULL),
251 ITEM_FACTORY_ENTRY("/View/<separator>", NULL, NULL, 0, "<Separator>", NULL),
252 ITEM_FACTORY_ENTRY("/View/Packet _List", NULL, packet_list_show_cb, 0, "<CheckItem>", NULL),
253 ITEM_FACTORY_ENTRY("/View/Packet _Details", NULL, tree_view_show_cb, 0, "<CheckItem>", NULL),
254 ITEM_FACTORY_ENTRY("/View/Packet _Bytes", NULL, byte_view_show_cb, 0, "<CheckItem>", NULL),
255 ITEM_FACTORY_ENTRY("/View/<separator>", NULL, NULL, 0, "<Separator>", NULL),
256 ITEM_FACTORY_ENTRY("/View/_Time Display Format", NULL, NULL, 0, "<Branch>", NULL),
257 ITEM_FACTORY_ENTRY("/View/Time Display Format/Date and Time of Day: 1970-01-01 01:02:03.123456", NULL, timestamp_absolute_date_cb,
258 0, "<RadioItem>", NULL),
259 ITEM_FACTORY_ENTRY("/View/Time Display Format/Time of Day: 01:02:03.123456", NULL, timestamp_absolute_cb,
260 0, "/View/Time Display Format/Date and Time of Day: 1970-01-01 01:02:03.123456", NULL),
261 ITEM_FACTORY_ENTRY("/View/Time Display Format/Seconds Since Beginning of Capture: 123.123456", NULL, timestamp_relative_cb,
262 0, "/View/Time Display Format/Date and Time of Day: 1970-01-01 01:02:03.123456", NULL),
263 ITEM_FACTORY_ENTRY("/View/Time Display Format/Seconds Since Previous Packet: 1.123456", NULL, timestamp_delta_cb,
264 0, "/View/Time Display Format/Date and Time of Day: 1970-01-01 01:02:03.123456", NULL),
265 ITEM_FACTORY_ENTRY("/View/Time Display Format/<separator>", NULL, NULL, 0, "<Separator>", NULL),
266 ITEM_FACTORY_ENTRY("/View/Time Display Format/Automatic (File Format Precision)", NULL, timestamp_auto_cb,
267 0, "<RadioItem>", NULL),
268 ITEM_FACTORY_ENTRY("/View/Time Display Format/Seconds: 0", NULL, timestamp_sec_cb,
269 0, "/View/Time Display Format/Automatic (File Format Precision)", NULL),
270 ITEM_FACTORY_ENTRY("/View/Time Display Format/Deciseconds: 0.1", NULL, timestamp_dsec_cb,
271 0, "/View/Time Display Format/Automatic (File Format Precision)", NULL),
272 ITEM_FACTORY_ENTRY("/View/Time Display Format/Centiseconds: 0.12", NULL, timestamp_csec_cb,
273 0, "/View/Time Display Format/Automatic (File Format Precision)", NULL),
274 ITEM_FACTORY_ENTRY("/View/Time Display Format/Milliseconds: 0.123", NULL, timestamp_msec_cb,
275 0, "/View/Time Display Format/Automatic (File Format Precision)", NULL),
276 ITEM_FACTORY_ENTRY("/View/Time Display Format/Microseconds: 0.123456", NULL, timestamp_usec_cb,
277 0, "/View/Time Display Format/Automatic (File Format Precision)", NULL),
278 ITEM_FACTORY_ENTRY("/View/Time Display Format/Nanoseconds: 0.123456789", NULL, timestamp_nsec_cb,
279 0, "/View/Time Display Format/Automatic (File Format Precision)", NULL),
280 ITEM_FACTORY_ENTRY("/View/Name Resol_ution", NULL, NULL, 0, "<Branch>", NULL),
281 ITEM_FACTORY_ENTRY("/View/Name Resolution/_Resolve Name", NULL, resolve_name_cb, 0, NULL, NULL),
282 ITEM_FACTORY_ENTRY("/View/Name Resolution/<separator>", NULL, NULL, 0, "<Separator>", NULL),
283 ITEM_FACTORY_ENTRY("/View/Name Resolution/Enable for _MAC Layer", NULL, name_resolution_mac_cb, 0, "<CheckItem>", NULL),
284 ITEM_FACTORY_ENTRY("/View/Name Resolution/Enable for _Network Layer", NULL, name_resolution_network_cb, 0, "<CheckItem>", NULL),
285 ITEM_FACTORY_ENTRY("/View/Name Resolution/Enable for _Transport Layer", NULL, name_resolution_transport_cb, 0, "<CheckItem>", NULL),
286 ITEM_FACTORY_ENTRY("/View/Colorize Packet List", NULL, colorize_cb, 0, "<CheckItem>", NULL),
288 ITEM_FACTORY_ENTRY("/View/Auto Scroll in Li_ve Capture", NULL, auto_scroll_live_cb, 0, "<CheckItem>", NULL),
290 ITEM_FACTORY_ENTRY("/View/<separator>", NULL, NULL, 0, "<Separator>", NULL),
291 ITEM_FACTORY_STOCK_ENTRY("/View/_Zoom In", "<control>plus", view_zoom_in_cb,
292 0, GTK_STOCK_ZOOM_IN),
293 ITEM_FACTORY_STOCK_ENTRY("/View/Zoom _Out", "<control>minus", view_zoom_out_cb,
294 0, GTK_STOCK_ZOOM_OUT),
295 ITEM_FACTORY_STOCK_ENTRY("/View/_Normal Size", "<control>equal", view_zoom_100_cb,
296 0, GTK_STOCK_ZOOM_100),
297 ITEM_FACTORY_STOCK_ENTRY("/View/Resize All Columns", NULL, packet_list_resize_columns_cb,
298 0, ETHEREAL_STOCK_RESIZE_COLUMNS),
299 ITEM_FACTORY_ENTRY("/View/<separator>", NULL, NULL, 0, "<Separator>", NULL),
300 ITEM_FACTORY_ENTRY("/View/E_xpand Subtrees", NULL, expand_tree_cb, 0, NULL, NULL),
301 ITEM_FACTORY_ENTRY("/View/_Expand All", NULL, expand_all_cb,
303 ITEM_FACTORY_ENTRY("/View/Collapse _All", NULL, collapse_all_cb,
305 ITEM_FACTORY_ENTRY("/View/<separator>", NULL, NULL, 0, "<Separator>", NULL),
306 ITEM_FACTORY_STOCK_ENTRY("/View/_Coloring Rules...", NULL, color_display_cb,
307 0, GTK_STOCK_SELECT_COLOR),
308 ITEM_FACTORY_ENTRY("/View/<separator>", NULL, NULL, 0, "<Separator>", NULL),
309 ITEM_FACTORY_ENTRY("/View/Show Packet in New _Window", NULL,
310 new_window_cb, 0, NULL, NULL),
311 ITEM_FACTORY_STOCK_ENTRY("/View/_Reload", "<control>R", file_reload_cmd_cb,
312 0, GTK_STOCK_REFRESH),
313 ITEM_FACTORY_ENTRY("/_Go", NULL, NULL, 0, "<Branch>", NULL),
314 ITEM_FACTORY_STOCK_ENTRY("/Go/_Back", "<alt>Left",
315 history_back_cb, 0, GTK_STOCK_GO_BACK),
316 ITEM_FACTORY_STOCK_ENTRY("/Go/_Forward", "<alt>Right",
317 history_forward_cb, 0, GTK_STOCK_GO_FORWARD),
318 ITEM_FACTORY_STOCK_ENTRY("/Go/_Go to Packet...", "<control>G",
319 goto_frame_cb, 0, GTK_STOCK_JUMP_TO),
320 ITEM_FACTORY_ENTRY("/Go/Go to _Corresponding Packet", NULL, goto_framenum_cb,
322 ITEM_FACTORY_ENTRY("/Go/<separator>", NULL, NULL, 0, "<Separator>", NULL),
323 ITEM_FACTORY_STOCK_ENTRY("/Go/F_irst Packet", NULL,
324 goto_top_frame_cb, 0, GTK_STOCK_GOTO_TOP),
325 ITEM_FACTORY_STOCK_ENTRY("/Go/_Last Packet", NULL,
326 goto_bottom_frame_cb, 0, GTK_STOCK_GOTO_BOTTOM),
328 ITEM_FACTORY_ENTRY("/_Capture", NULL, NULL, 0, "<Branch>", NULL),
329 ITEM_FACTORY_STOCK_ENTRY("/Capture/_Interfaces...", NULL,
330 capture_if_cb, 0, ETHEREAL_STOCK_CAPTURE_INTERFACES),
331 ITEM_FACTORY_STOCK_ENTRY("/Capture/_Options...", "<control>K",
332 capture_prep_cb, 0, ETHEREAL_STOCK_CAPTURE_OPTIONS),
333 ITEM_FACTORY_STOCK_ENTRY("/Capture/_Start", NULL,
334 capture_start_cb, 0, ETHEREAL_STOCK_CAPTURE_START),
335 ITEM_FACTORY_STOCK_ENTRY("/Capture/S_top", "<control>E", capture_stop_cb,
336 0, ETHEREAL_STOCK_CAPTURE_STOP),
337 ITEM_FACTORY_STOCK_ENTRY("/Capture/_Restart", NULL, capture_restart_cb,
338 0, ETHEREAL_STOCK_CAPTURE_RESTART),
339 ITEM_FACTORY_STOCK_ENTRY("/Capture/Capture _Filters...", NULL, cfilter_dialog_cb,
340 0, ETHEREAL_STOCK_CAPTURE_FILTER),
341 #endif /* HAVE_LIBPCAP */
342 ITEM_FACTORY_ENTRY("/_Analyze", NULL, NULL, 0, "<Branch>", NULL),
343 ITEM_FACTORY_STOCK_ENTRY("/Analyze/_Display Filters...", NULL, dfilter_dialog_cb,
344 0, ETHEREAL_STOCK_DISPLAY_FILTER),
345 ITEM_FACTORY_ENTRY("/Analyze/Appl_y as Filter", NULL, NULL, 0, "<Branch>", NULL),
346 ITEM_FACTORY_ENTRY("/Analyze/Apply as Filter/_Selected", NULL, match_selected_ptree_cb,
347 MATCH_SELECTED_REPLACE|MATCH_SELECTED_APPLY_NOW, NULL, NULL),
348 ITEM_FACTORY_ENTRY("/Analyze/Apply as Filter/_Not Selected", NULL, match_selected_ptree_cb,
349 MATCH_SELECTED_NOT|MATCH_SELECTED_APPLY_NOW, NULL, NULL),
350 ITEM_FACTORY_ENTRY("/Analyze/Apply as Filter/... _and Selected", NULL, match_selected_ptree_cb,
351 MATCH_SELECTED_AND|MATCH_SELECTED_APPLY_NOW, NULL, NULL),
352 ITEM_FACTORY_ENTRY("/Analyze/Apply as Filter/... _or Selected", NULL, match_selected_ptree_cb,
353 MATCH_SELECTED_OR|MATCH_SELECTED_APPLY_NOW, NULL, NULL),
354 ITEM_FACTORY_ENTRY("/Analyze/Apply as Filter/... a_nd not Selected", NULL, match_selected_ptree_cb,
355 MATCH_SELECTED_AND_NOT|MATCH_SELECTED_APPLY_NOW, NULL, NULL),
356 ITEM_FACTORY_ENTRY("/Analyze/Apply as Filter/... o_r not Selected", NULL, match_selected_ptree_cb,
357 MATCH_SELECTED_OR_NOT|MATCH_SELECTED_APPLY_NOW, NULL, NULL),
358 ITEM_FACTORY_ENTRY("/Analyze/_Prepare a Filter", NULL, NULL, 0, "<Branch>", NULL),
359 ITEM_FACTORY_ENTRY("/Analyze/Prepare a Filter/_Selected", NULL, match_selected_ptree_cb,
360 MATCH_SELECTED_REPLACE, NULL, NULL),
361 ITEM_FACTORY_ENTRY("/Analyze/Prepare a Filter/_Not Selected", NULL, match_selected_ptree_cb,
362 MATCH_SELECTED_NOT, NULL, NULL),
363 ITEM_FACTORY_ENTRY("/Analyze/Prepare a Filter/... _and Selected", NULL, match_selected_ptree_cb,
364 MATCH_SELECTED_AND, NULL, NULL),
365 ITEM_FACTORY_ENTRY("/Analyze/Prepare a Filter/... _or Selected", NULL, match_selected_ptree_cb,
366 MATCH_SELECTED_OR, NULL, NULL),
367 ITEM_FACTORY_ENTRY("/Analyze/Prepare a Filter/... a_nd not Selected", NULL, match_selected_ptree_cb,
368 MATCH_SELECTED_AND_NOT, NULL, NULL),
369 ITEM_FACTORY_ENTRY("/Analyze/Prepare a Filter/... o_r not Selected", NULL, match_selected_ptree_cb,
370 MATCH_SELECTED_OR_NOT, NULL, NULL),
371 ITEM_FACTORY_ENTRY("/Analyze/<separator>", NULL, NULL, 0, "<Separator>", NULL),
372 ITEM_FACTORY_STOCK_ENTRY("/Analyze/_Enabled Protocols...", "<shift><control>R", proto_cb, 0, ETHEREAL_STOCK_CHECKBOX),
373 ITEM_FACTORY_STOCK_ENTRY("/Analyze/Decode _As...", NULL, decode_as_cb,
374 0, ETHEREAL_STOCK_DECODE_AS),
375 ITEM_FACTORY_STOCK_ENTRY("/Analyze/_User Specified Decodes...", NULL,
376 decode_show_cb, 0, ETHEREAL_STOCK_DECODE_AS),
377 ITEM_FACTORY_ENTRY("/Analyze/<separator>", NULL, NULL, 0, "<Separator>", NULL),
378 ITEM_FACTORY_ENTRY("/Analyze/_Follow TCP Stream", NULL,
379 follow_stream_cb, 0, NULL, NULL),
380 ITEM_FACTORY_ENTRY("/Analyze/_Follow SSL Stream", NULL,
381 ssl_stream_cb, 0, NULL, NULL),
382 ITEM_FACTORY_ENTRY("/_Statistics", NULL, NULL, 0, "<Branch>", NULL),
383 ITEM_FACTORY_STOCK_ENTRY("/Statistics/_Summary", NULL, summary_open_cb, 0, GTK_STOCK_PROPERTIES),
384 ITEM_FACTORY_ENTRY("/Statistics/_Protocol Hierarchy", NULL,
385 proto_hier_stats_cb, 0, NULL, NULL),
386 ITEM_FACTORY_STOCK_ENTRY("/Statistics/Conversations", NULL,
387 init_conversation_notebook_cb, 0, ETHEREAL_STOCK_CONVERSATIONS),
388 ITEM_FACTORY_STOCK_ENTRY("/Statistics/Endpoints", NULL,
389 init_hostlist_notebook_cb, 0, ETHEREAL_STOCK_ENDPOINTS),
390 ITEM_FACTORY_ENTRY("/_Help", NULL, NULL, 0, "<Branch>", NULL),
391 ITEM_FACTORY_STOCK_ENTRY("/Help/_Contents", "F1", topic_menu_cb, HELP_CONTENT, GTK_STOCK_HELP),
392 ITEM_FACTORY_ENTRY("/Help/_Supported Protocols", NULL, supported_cb, 0, NULL, NULL),
393 #if (GLIB_MAJOR_VERSION >= 2)
394 #ifdef ETHEREAL_EUG_DIR
395 ITEM_FACTORY_ENTRY("/Help/User's Guide", NULL, topic_menu_cb, HELP_CONTENT, NULL, NULL),
397 ITEM_FACTORY_ENTRY("/Help/Manual Pages", NULL, NULL, 0, "<Branch>", NULL),
398 ITEM_FACTORY_ENTRY("/Help/Manual Pages/Ethereal", NULL, topic_menu_cb, LOCALPAGE_MAN_ETHEREAL, NULL, NULL),
399 ITEM_FACTORY_ENTRY("/Help/Manual Pages/Ethereal Filter", NULL, topic_menu_cb, LOCALPAGE_MAN_ETHEREAL_FILTER, NULL, NULL),
400 ITEM_FACTORY_ENTRY("/Help/Manual Pages/<separator>", NULL, NULL, 0, "<Separator>", NULL),
401 ITEM_FACTORY_ENTRY("/Help/Manual Pages/Tethereal", NULL, topic_menu_cb, LOCALPAGE_MAN_TETHEREAL, NULL, NULL),
402 ITEM_FACTORY_ENTRY("/Help/Manual Pages/Dumpcap", NULL, topic_menu_cb, LOCALPAGE_MAN_DUMPCAP, NULL, NULL),
403 ITEM_FACTORY_ENTRY("/Help/Manual Pages/Mergecap", NULL, topic_menu_cb, LOCALPAGE_MAN_MERGECAP, NULL, NULL),
404 ITEM_FACTORY_ENTRY("/Help/Manual Pages/Editcap", NULL, topic_menu_cb, LOCALPAGE_MAN_EDITCAP, NULL, NULL),
405 ITEM_FACTORY_ENTRY("/Help/Manual Pages/Text2pcap", NULL, topic_menu_cb, LOCALPAGE_MAN_TEXT2PCAP, NULL, NULL),
406 ITEM_FACTORY_ENTRY("/Help/Ethereal Online", NULL, NULL, 0, "<Branch>", NULL),
407 ITEM_FACTORY_STOCK_ENTRY("/Help/Ethereal Online/Home Page", NULL, topic_menu_cb, ONLINEPAGE_HOME, GTK_STOCK_HOME),
408 ITEM_FACTORY_STOCK_ENTRY("/Help/Ethereal Online/Wiki", NULL, topic_menu_cb, ONLINEPAGE_WIKI, ETHEREAL_STOCK_WIKI),
409 ITEM_FACTORY_STOCK_ENTRY("/Help/Ethereal Online/User's Guide", NULL, topic_menu_cb, ONLINEPAGE_USERGUIDE, ETHEREAL_STOCK_WEB_SUPPORT),
410 ITEM_FACTORY_ENTRY("/Help/Ethereal Online/FAQ's", NULL, topic_menu_cb, ONLINEPAGE_FAQ, NULL, NULL),
411 ITEM_FACTORY_ENTRY("/Help/Ethereal Online/Downloads", NULL, topic_menu_cb, ONLINEPAGE_DOWNLOAD, NULL, NULL),
412 ITEM_FACTORY_ENTRY("/Help/Ethereal Online/Example Files", NULL, topic_menu_cb, ONLINEPAGE_SAMPLE_FILES, NULL, NULL),
414 ITEM_FACTORY_ENTRY("/Help/<separator>", NULL, NULL, 0, "<Separator>", NULL),
415 ITEM_FACTORY_STOCK_ENTRY("/Help/_About Ethereal", NULL, about_ethereal_cb,
416 0, ETHEREAL_STOCK_ABOUT)
420 /* calculate the number of menu_items */
421 static int nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
423 /* packet list popup */
424 static GtkItemFactoryEntry packet_list_menu_items[] =
426 ITEM_FACTORY_ENTRY("/Mark Packet (toggle)", NULL, packet_list_mark_frame_cb, 0, NULL, NULL),
427 ITEM_FACTORY_ENTRY("/Time Reference", NULL, NULL, 0, "<Branch>", NULL),
428 ITEM_FACTORY_STOCK_ENTRY("/Time Reference/Set Time Reference (toggle)", NULL, reftime_frame_cb, REFTIME_TOGGLE, ETHEREAL_STOCK_TIME),
429 ITEM_FACTORY_ENTRY("/Time Reference/Find Next", NULL, reftime_frame_cb, REFTIME_FIND_NEXT, NULL, NULL),
430 ITEM_FACTORY_ENTRY("/Time Reference/Find Previous", NULL, reftime_frame_cb, REFTIME_FIND_PREV, NULL, NULL),
432 ITEM_FACTORY_ENTRY("/<separator>", NULL, NULL, 0, "<Separator>", NULL),
434 ITEM_FACTORY_ENTRY("/Apply as Filter", NULL, NULL, 0, "<Branch>", NULL),
435 ITEM_FACTORY_ENTRY("/Apply as Filter/_Selected", NULL, match_selected_plist_cb,
436 MATCH_SELECTED_REPLACE|MATCH_SELECTED_APPLY_NOW, NULL, NULL),
437 ITEM_FACTORY_ENTRY("/Apply as Filter/_Not Selected", NULL, match_selected_plist_cb,
438 MATCH_SELECTED_NOT|MATCH_SELECTED_APPLY_NOW, NULL, NULL),
439 ITEM_FACTORY_ENTRY("/Apply as Filter/... _and Selected", NULL, match_selected_plist_cb,
440 MATCH_SELECTED_AND|MATCH_SELECTED_APPLY_NOW, NULL, NULL),
441 ITEM_FACTORY_ENTRY("/Apply as Filter/... _or Selected", NULL, match_selected_plist_cb,
442 MATCH_SELECTED_OR|MATCH_SELECTED_APPLY_NOW, NULL, NULL),
443 ITEM_FACTORY_ENTRY("/Apply as Filter/... a_nd not Selected", NULL, match_selected_plist_cb,
444 MATCH_SELECTED_AND_NOT|MATCH_SELECTED_APPLY_NOW, NULL, NULL),
445 ITEM_FACTORY_ENTRY("/Apply as Filter/... o_r not Selected", NULL, match_selected_plist_cb,
446 MATCH_SELECTED_OR_NOT|MATCH_SELECTED_APPLY_NOW, NULL, NULL),
448 ITEM_FACTORY_ENTRY("/Prepare a Filter", NULL, NULL, 0, "<Branch>", NULL),
449 ITEM_FACTORY_ENTRY("/Prepare a Filter/_Selected", NULL, match_selected_plist_cb,
450 MATCH_SELECTED_REPLACE, NULL, NULL),
451 ITEM_FACTORY_ENTRY("/Prepare a Filter/_Not Selected", NULL, match_selected_plist_cb,
452 MATCH_SELECTED_NOT, NULL, NULL),
453 ITEM_FACTORY_ENTRY("/Prepare a Filter/... _and Selected", NULL, match_selected_plist_cb,
454 MATCH_SELECTED_AND, NULL, NULL),
455 ITEM_FACTORY_ENTRY("/Prepare a Filter/... _or Selected", NULL, match_selected_plist_cb,
456 MATCH_SELECTED_OR, NULL, NULL),
457 ITEM_FACTORY_ENTRY("/Prepare a Filter/... a_nd not Selected", NULL, match_selected_plist_cb,
458 MATCH_SELECTED_AND_NOT, NULL, NULL),
459 ITEM_FACTORY_ENTRY("/Prepare a Filter/... o_r not Selected", NULL, match_selected_plist_cb,
460 MATCH_SELECTED_OR_NOT, NULL, NULL),
462 ITEM_FACTORY_ENTRY("/Follow TCP Stream", NULL, follow_stream_cb,
464 ITEM_FACTORY_ENTRY("/Follow SSL Stream", NULL, ssl_stream_cb,
467 ITEM_FACTORY_ENTRY("/<separator>", NULL, NULL, 0, "<Separator>", NULL),
469 ITEM_FACTORY_STOCK_ENTRY("/Decode As...", NULL, decode_as_cb, 0, ETHEREAL_STOCK_DECODE_AS),
470 ITEM_FACTORY_STOCK_ENTRY("/Print...", NULL, file_print_selected_cmd_cb, 0, GTK_STOCK_PRINT),
471 ITEM_FACTORY_ENTRY("/Show Packet in New Window", NULL, new_window_cb,
475 static GtkItemFactoryEntry tree_view_menu_items[] =
477 ITEM_FACTORY_ENTRY("/Expand Subtrees", NULL, expand_tree_cb, 0, NULL, NULL),
478 ITEM_FACTORY_ENTRY("/Expand All", NULL, expand_all_cb, 0, NULL, NULL),
479 ITEM_FACTORY_ENTRY("/Collapse All", NULL, collapse_all_cb, 0, NULL, NULL),
481 ITEM_FACTORY_ENTRY("/<separator>", NULL, NULL, 0, "<Separator>", NULL),
483 ITEM_FACTORY_ENTRY("/Apply as Filter", NULL, NULL, 0, "<Branch>", NULL),
484 ITEM_FACTORY_ENTRY("/Apply as Filter/_Selected", NULL, match_selected_ptree_cb,
485 MATCH_SELECTED_REPLACE|MATCH_SELECTED_APPLY_NOW, NULL, NULL),
486 ITEM_FACTORY_ENTRY("/Apply as Filter/_Not Selected", NULL, match_selected_ptree_cb,
487 MATCH_SELECTED_NOT|MATCH_SELECTED_APPLY_NOW, NULL, NULL),
488 ITEM_FACTORY_ENTRY("/Apply as Filter/... _and Selected", NULL, match_selected_ptree_cb,
489 MATCH_SELECTED_AND|MATCH_SELECTED_APPLY_NOW, NULL, NULL),
490 ITEM_FACTORY_ENTRY("/Apply as Filter/... _or Selected", NULL, match_selected_ptree_cb,
491 MATCH_SELECTED_OR|MATCH_SELECTED_APPLY_NOW, NULL, NULL),
492 ITEM_FACTORY_ENTRY("/Apply as Filter/... a_nd not Selected", NULL, match_selected_ptree_cb,
493 MATCH_SELECTED_AND_NOT|MATCH_SELECTED_APPLY_NOW, NULL, NULL),
494 ITEM_FACTORY_ENTRY("/Apply as Filter/... o_r not Selected", NULL, match_selected_ptree_cb,
495 MATCH_SELECTED_OR_NOT|MATCH_SELECTED_APPLY_NOW, NULL, NULL),
497 ITEM_FACTORY_ENTRY("/Prepare a Filter", NULL, NULL, 0, "<Branch>", NULL),
498 ITEM_FACTORY_ENTRY("/Prepare a Filter/_Selected", NULL, match_selected_ptree_cb,
499 MATCH_SELECTED_REPLACE, NULL, NULL),
500 ITEM_FACTORY_ENTRY("/Prepare a Filter/_Not Selected", NULL, match_selected_ptree_cb,
501 MATCH_SELECTED_NOT, NULL, NULL),
502 ITEM_FACTORY_ENTRY("/Prepare a Filter/... _and Selected", NULL, match_selected_ptree_cb,
503 MATCH_SELECTED_AND, NULL, NULL),
504 ITEM_FACTORY_ENTRY("/Prepare a Filter/... _or Selected", NULL, match_selected_ptree_cb,
505 MATCH_SELECTED_OR, NULL, NULL),
506 ITEM_FACTORY_ENTRY("/Prepare a Filter/... a_nd not Selected", NULL, match_selected_ptree_cb,
507 MATCH_SELECTED_AND_NOT, NULL, NULL),
508 ITEM_FACTORY_ENTRY("/Prepare a Filter/... o_r not Selected", NULL, match_selected_ptree_cb,
509 MATCH_SELECTED_OR_NOT, NULL, NULL),
511 ITEM_FACTORY_ENTRY("/Follow TCP Stream", NULL, follow_stream_cb,
513 ITEM_FACTORY_ENTRY("/Follow SSL Stream", NULL, ssl_stream_cb,
516 ITEM_FACTORY_ENTRY("/<separator>", NULL, NULL, 0, "<Separator>", NULL),
518 ITEM_FACTORY_STOCK_ENTRY("/Wiki Protocol Page", NULL, selected_ptree_info_cb,
519 0, ETHEREAL_STOCK_WIKI),
520 ITEM_FACTORY_STOCK_ENTRY("/Filter Field Reference", NULL, selected_ptree_ref_cb,
521 0, ETHEREAL_STOCK_INTERNET),
522 ITEM_FACTORY_STOCK_ENTRY("/Field Information", NULL, selected_ptree_field_url_cb,
523 0, ETHEREAL_STOCK_INTERNET),
524 ITEM_FACTORY_ENTRY("/Protocol Preferences...", NULL, properties_cb,
526 ITEM_FACTORY_ENTRY("/<separator>", NULL, NULL, 0, "<Separator>", NULL),
527 ITEM_FACTORY_STOCK_ENTRY("/Decode As...", NULL, decode_as_cb, 0, ETHEREAL_STOCK_DECODE_AS),
528 ITEM_FACTORY_ENTRY("/_Resolve Name", NULL, resolve_name_cb, 0, NULL, NULL),
529 ITEM_FACTORY_ENTRY("/_Go to Corresponding Packet", NULL, goto_framenum_cb, 0, NULL, NULL),
532 static GtkItemFactoryEntry hexdump_menu_items[] =
534 ITEM_FACTORY_ENTRY("/Copy", NULL, copy_hex_cb,
536 ITEM_FACTORY_ENTRY("/Export Selected Packet Bytes...", NULL, savehex_cb,
540 static int initialize = TRUE;
541 static GtkItemFactory *main_menu_factory = NULL;
542 static GtkItemFactory *packet_list_menu_factory = NULL;
543 static GtkItemFactory *tree_view_menu_factory = NULL;
544 static GtkItemFactory *hexdump_menu_factory = NULL;
546 static GSList *popup_menu_list = NULL;
548 static GtkAccelGroup *grp;
551 main_menu_new(GtkAccelGroup ** table) {
554 grp = gtk_accel_group_new();
559 menubar = main_menu_factory->widget;
573 packet_list_menu_factory = gtk_item_factory_new(GTK_TYPE_MENU, "<main>", NULL);
574 popup_menu_object = gtk_menu_new();
575 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);
576 OBJECT_SET_DATA(popup_menu_object, PM_PACKET_LIST_KEY,
577 packet_list_menu_factory->widget);
578 popup_menu_list = g_slist_append((GSList *)popup_menu_list, packet_list_menu_factory);
580 tree_view_menu_factory = gtk_item_factory_new(GTK_TYPE_MENU, "<main>", NULL);
581 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);
582 OBJECT_SET_DATA(popup_menu_object, PM_TREE_VIEW_KEY,
583 tree_view_menu_factory->widget);
584 popup_menu_list = g_slist_append((GSList *)popup_menu_list, tree_view_menu_factory);
586 hexdump_menu_factory = gtk_item_factory_new(GTK_TYPE_MENU, "<main>", NULL);
587 gtk_item_factory_create_items_ac(hexdump_menu_factory, sizeof(hexdump_menu_items)/sizeof(hexdump_menu_items[0]), hexdump_menu_items, popup_menu_object, 2);
588 OBJECT_SET_DATA(popup_menu_object, PM_HEXDUMP_KEY,
589 hexdump_menu_factory->widget);
590 popup_menu_list = g_slist_append((GSList *)popup_menu_list, hexdump_menu_factory);
593 main_menu_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", grp);
594 gtk_item_factory_create_items_ac(main_menu_factory, nmenu_items, menu_items, NULL, 2);
596 merge_all_tap_menus(tap_menu_tree_root);
598 /* Initialize enabled/disabled state of menu items */
599 set_menus_for_unsaved_capture_file(FALSE);
600 set_menus_for_capture_file(FALSE);
602 /* Un-#if this when we actually implement Cut/Copy/Paste.
603 Then make sure you enable them when they can be done. */
604 set_menu_sensitivity(main_menu_factory, "/Edit/Cut", FALSE);
605 set_menu_sensitivity(main_menu_factory, "/Edit/Copy", FALSE);
606 set_menu_sensitivity(main_menu_factory, "/Edit/Paste", FALSE);
609 set_menus_for_captured_packets(FALSE);
610 set_menus_for_selected_packet(&cfile);
611 set_menus_for_selected_tree_row(&cfile);
612 set_menus_for_capture_in_progress(FALSE);
613 set_menus_for_file_set(/* dialog */TRUE, /* previous file */ FALSE, /* next_file */ FALSE);
615 /* init with an empty recent files list */
616 clear_menu_recent_capture_file_cmd_cb(NULL, NULL);
621 static gint tap_menu_item_add_compare(gconstpointer a, gconstpointer b)
624 ((const menu_item_t *) a)->name,
625 ((const menu_item_t *) b)->name);
629 /* add a menuitem below the current node */
630 static GList * tap_menu_item_add(
633 GtkItemFactoryCallback callback,
634 gboolean (*selected_packet_enabled)(frame_data *, epan_dissect_t *),
635 gboolean (*selected_tree_row_enabled)(field_info *),
636 gpointer callback_data,
643 child = g_malloc(sizeof (menu_item_t));
644 child->group = group;
646 child->callback = callback;
647 child->selected_packet_enabled = selected_packet_enabled;
648 child->selected_tree_row_enabled = selected_tree_row_enabled;
649 child->callback_data = callback_data;
650 child->enabled = FALSE;
651 child->children = NULL;
653 /* insert the new child node into the parent */
654 curr = curnode->data;
655 curr->children = g_list_insert_sorted(curr->children, child, tap_menu_item_add_compare);
657 /* return the new node */
658 /* XXX: improve this */
659 return g_list_find(curr->children, child);
663 * Add a new menu item for a tap.
664 * This must be called after we've created the main menu, so it can't
665 * be called from the routine that registers taps - we have to introduce
666 * another per-tap registration routine.
668 * "callback" gets called when the menu item is selected; it should do
669 * the work of creating the tap window.
671 * "selected_packet_enabled" gets called by "set_menus_for_selected_packet()";
672 * it's passed a Boolean that's TRUE if a packet is selected and FALSE
673 * otherwise, and should return TRUE if the tap will work now (which
674 * might depend on whether a packet is selected and, if one is, on the
675 * packet) and FALSE if not.
677 * "selected_tree_row_enabled" gets called by
678 * "set_menus_for_selected_tree_row()"; it's passed a Boolean that's TRUE if
679 * a protocol tree row is selected and FALSE otherwise, and should return
680 * TRUE if the tap will work now (which might depend on whether a tree row
681 * is selected and, if one is, on the tree row) and FALSE if not.
684 register_stat_menu_item(
686 REGISTER_STAT_GROUP_E group,
687 GtkItemFactoryCallback callback,
688 gboolean (*selected_packet_enabled)(frame_data *, epan_dissect_t *),
689 gboolean (*selected_tree_row_enabled)(field_info *),
690 gpointer callback_data)
692 /*static const char toolspath[] = "/Statistics/";*/
693 const char *toolspath;
702 * The menu path must be relative.
704 g_assert(*name != '/');
707 case(REGISTER_STAT_GROUP_GENERIC): toolspath = "/Statistics/"; break;
708 case(REGISTER_STAT_GROUP_CONVERSATION_LIST): toolspath = "/Statistics/_Conversation List/"; break;
709 case(REGISTER_STAT_GROUP_ENDPOINT_LIST): toolspath = "/Statistics/_Endpoint List/"; break;
710 case(REGISTER_STAT_GROUP_RESPONSE_TIME): toolspath = "/Statistics/Service _Response Time/"; break;
711 case(REGISTER_STAT_GROUP_TELEPHONY): toolspath = "/Statistics/"; break;
712 case(REGISTER_STAT_GROUP_NONE): toolspath = "/Statistics/"; break;
713 case(REGISTER_ANALYZE_GROUP_NONE): toolspath = "/Analyze/"; break;
719 /* add the (empty) root node, if not already done */
720 if(tap_menu_tree_root == NULL) {
721 child = g_malloc0(sizeof (menu_item_t));
722 tap_menu_tree_root = g_list_append(NULL, child);
726 * Create any submenus required.
728 curnode = tap_menu_tree_root;
730 while ((p = strchr(p, '/')) != NULL) {
732 * OK, everything between "name" and "p" is
733 * a menu relative subtree into which the menu item
736 * Construct the absolute path name of that subtree.
738 menupathlen = strlen(toolspath) + 1 + (p - name);
739 menupath = g_malloc(menupathlen);
740 strcpy(menupath, toolspath);
741 strncat(menupath, name, p - name);
744 * Does there exist an entry with that path at this
745 * level of the Analyze menu tree?
747 child = curnode->data;
748 for (childnode = child->children; childnode != NULL; childnode = childnode->next) {
749 child = childnode->data;
750 if (strcmp(child->name, menupath) == 0)
753 if (childnode == NULL) {
755 * No. Create such an item as a subtree, and
756 * add it to the Tools menu tree.
758 childnode = tap_menu_item_add(
759 menupath, group, NULL, NULL ,NULL, NULL, curnode);
762 * Yes. We don't need this "menupath" any longer.
769 * Skip over the '/' we found.
775 * Construct the main menu path for the menu item.
777 menupathlen = strlen(toolspath) + 1 + strlen(name);
778 menupath = g_malloc(menupathlen);
779 strcpy(menupath, toolspath);
780 strcat(menupath, name);
783 * Construct an item factory entry for the item, and add it to
787 menupath, group, callback,
788 selected_packet_enabled, selected_tree_row_enabled,
789 callback_data, curnode);
793 static guint merge_tap_menus_layered(GList *node, gint group) {
794 GtkItemFactoryEntry *entry;
797 menu_item_t *node_data = node->data;
800 * Is this a leaf node or an interior node?
802 if (node_data->children == NULL) {
808 * The root node doesn't correspond to a menu tree item; it
809 * has a null name pointer.
811 if (node_data->name != NULL && group == node_data->group) {
812 entry = g_malloc0(sizeof (GtkItemFactoryEntry));
813 entry->path = node_data->name;
814 entry->callback = node_data->callback;
815 #if GTK_MAJOR_VERSION >= 2
817 case(REGISTER_STAT_GROUP_NONE):
819 case(REGISTER_STAT_GROUP_GENERIC):
821 case(REGISTER_STAT_GROUP_CONVERSATION_LIST):
822 entry->item_type = "<StockItem>";
823 entry->extra_data = ETHEREAL_STOCK_CONVERSATIONS;
825 case(REGISTER_STAT_GROUP_ENDPOINT_LIST):
826 entry->item_type = "<StockItem>";
827 entry->extra_data = ETHEREAL_STOCK_ENDPOINTS;
829 case(REGISTER_STAT_GROUP_RESPONSE_TIME):
830 entry->item_type = "<StockItem>";
831 entry->extra_data = ETHEREAL_STOCK_TIME;
833 case(REGISTER_STAT_GROUP_TELEPHONY):
834 entry->item_type = "<StockItem>";
835 entry->extra_data = ETHEREAL_STOCK_TELEPHONY;
837 case(REGISTER_ANALYZE_GROUP_NONE):
840 g_assert_not_reached();
843 gtk_item_factory_create_item(main_menu_factory, entry, node_data->callback_data, 2);
844 set_menu_sensitivity(main_menu_factory, node_data->name, FALSE); /* no capture file yet */
849 * It's an interior node; call
850 * "merge_tap_menus_layered()" on all its children
854 * The root node doesn't correspond to a menu tree item; it
855 * has a null name pointer.
857 if (node_data->name != NULL && group == node_data->group) {
858 entry = g_malloc0(sizeof (GtkItemFactoryEntry));
859 entry->path = node_data->name;
860 entry->item_type = "<Branch>";
861 gtk_item_factory_create_item(main_menu_factory, entry,
863 set_menu_sensitivity(main_menu_factory, node_data->name,
864 FALSE); /* no children yet */
868 for (child = node_data->children; child != NULL; child =
870 added += merge_tap_menus_layered(child, group);
878 void merge_all_tap_menus(GList *node) {
879 GtkItemFactoryEntry *entry;
881 entry = g_malloc0(sizeof (GtkItemFactoryEntry));
882 entry->item_type = "<Separator>";
883 entry->path = "/Statistics/";
886 * merge only the menu items of the specific group,
887 * and then append a seperator
889 if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_GENERIC)) {
890 gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);
892 if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_CONVERSATION_LIST)) {
893 /*gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);*/
895 if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_ENDPOINT_LIST)) {
896 /*gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);*/
898 if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_RESPONSE_TIME)) {
899 gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);
901 if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_TELEPHONY)) {
902 gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);
904 if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_NONE)) {
905 /*gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);*/
907 if (merge_tap_menus_layered(node, REGISTER_ANALYZE_GROUP_NONE)) {
908 entry->path = "/Analyze/";
909 /*gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);*/
916 * Enable/disable menu sensitivity.
919 set_menu_sensitivity(GtkItemFactory *ifactory, const gchar *path, gint val)
922 GtkWidget *menu_item;
927 /* the underscore character regularly confuses things, as it will prevent finding
928 * the menu_item, so it has to be removed first */
929 dup = g_strdup(path);
940 if (ifactory == NULL) {
942 * Do it for all pop-up menus.
944 for (menu_list = popup_menu_list; menu_list != NULL;
945 menu_list = g_slist_next(menu_list))
946 set_menu_sensitivity(menu_list->data, dup, val);
949 * Do it for that particular menu.
951 if ((menu_item = gtk_item_factory_get_widget(ifactory, dup)) != NULL) {
952 if (GTK_IS_MENU(menu_item)) {
954 * "dup" refers to a submenu; "gtk_item_factory_get_widget()"
955 * gets the menu, not the item that, when selected, pops up
958 * We have to change the latter item's sensitivity, so that
959 * it shows up normally if sensitive and grayed-out if
962 menu_item = gtk_menu_get_attach_widget(GTK_MENU(menu_item));
964 gtk_widget_set_sensitive(menu_item, val);
966 /* be sure this menu item *is* existing */
967 g_assert_not_reached();
975 set_menu_object_data_meat(GtkItemFactory *ifactory, const gchar *path, const gchar *key, gpointer data)
977 GtkWidget *menu = NULL;
979 if ((menu = gtk_item_factory_get_widget(ifactory, path)) != NULL)
980 OBJECT_SET_DATA(menu, key, data);
984 set_menu_object_data (const gchar *path, const gchar *key, gpointer data) {
985 GSList *menu_list = popup_menu_list;
986 gchar *shortpath = strrchr(path, '/');
988 set_menu_object_data_meat(main_menu_factory, path, key, data);
989 while (menu_list != NULL) {
990 set_menu_object_data_meat(menu_list->data, shortpath, key, data);
991 menu_list = g_slist_next(menu_list);
996 /* Recently used capture files submenu:
997 * Submenu containing the recently used capture files.
998 * The capture filenames are always kept with the absolute path, to be independant
999 * of the current path.
1000 * They are only stored inside the labels of the submenu (no separate list). */
1002 #define MENU_RECENT_FILES_PATH "/File/Open Recent"
1003 #define MENU_RECENT_FILES_KEY "Recent File Name"
1006 update_menu_recent_capture_file1(GtkWidget *widget, gpointer cnt) {
1007 gchar *widget_cf_name;
1009 widget_cf_name = OBJECT_GET_DATA(widget, MENU_RECENT_FILES_KEY);
1011 /* if this menu item is a file, count it */
1012 if (widget_cf_name) {
1018 /* update the menu */
1020 update_menu_recent_capture_file(GtkWidget *submenu_recent_files) {
1023 gtk_container_foreach(GTK_CONTAINER(submenu_recent_files),
1024 update_menu_recent_capture_file1, &cnt);
1026 /* make parent menu item sensitive only, if we have any valid files in the list */
1027 set_menu_sensitivity(main_menu_factory, MENU_RECENT_FILES_PATH, cnt);
1031 /* remove the capture filename from the "Recent Files" menu */
1033 remove_menu_recent_capture_file(GtkWidget *widget, gpointer unused _U_) {
1034 GtkWidget *submenu_recent_files;
1035 gchar *widget_cf_name;
1038 widget_cf_name = OBJECT_GET_DATA(widget, MENU_RECENT_FILES_KEY);
1039 g_free(widget_cf_name);
1041 /* get the submenu container item */
1042 submenu_recent_files = gtk_item_factory_get_widget(main_menu_factory, MENU_RECENT_FILES_PATH);
1044 /* XXX: is this all we need to do, to free the menu item and its label?
1045 The reference count of widget will go to 0, so it'll be freed;
1046 will that free the label? */
1047 gtk_container_remove(GTK_CONTAINER(submenu_recent_files), widget);
1051 /* callback, if the user pushed the <Clear File List> item */
1053 clear_menu_recent_capture_file_cmd_cb(GtkWidget *w _U_, gpointer unused _U_) {
1054 GtkWidget *submenu_recent_files;
1057 submenu_recent_files = gtk_item_factory_get_widget(main_menu_factory, MENU_RECENT_FILES_PATH);
1059 gtk_container_foreach(GTK_CONTAINER(submenu_recent_files),
1060 remove_menu_recent_capture_file, NULL);
1062 update_menu_recent_capture_file(submenu_recent_files);
1066 /* callback, if the user pushed a recent file submenu item */
1068 menu_open_recent_file_cmd(GtkWidget *w)
1070 GtkWidget *submenu_recent_files;
1071 GtkWidget *menu_item_child;
1075 submenu_recent_files = gtk_item_factory_get_widget(main_menu_factory, MENU_RECENT_FILES_PATH);
1077 /* get capture filename from the menu item label */
1078 menu_item_child = (GTK_BIN(w))->child;
1079 gtk_label_get(GTK_LABEL(menu_item_child), &cf_name);
1081 /* open and read the capture file (this will close an existing file) */
1082 if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
1085 /* the capture file isn't existing any longer, remove menu item */
1086 /* XXX: ask user to remove item, it's maybe only a temporary problem */
1087 remove_menu_recent_capture_file(w, NULL);
1090 update_menu_recent_capture_file(submenu_recent_files);
1093 static void menu_open_recent_file_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
1097 /* save file first */
1098 file_save_as_cmd(after_save_open_recent_file, data);
1102 menu_open_recent_file_cmd(data);
1104 case(ESD_BTN_CANCEL):
1107 g_assert_not_reached();
1112 menu_open_recent_file_cmd_cb(GtkWidget *widget, gpointer data _U_) {
1116 if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
1117 /* user didn't saved his current file, ask him */
1118 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO_CANCEL,
1119 PRIMARY_TEXT_START "Save capture file before opening a new one?" PRIMARY_TEXT_END "\n\n"
1120 "If you open a new capture file without saving, your current capture data will be discarded.");
1121 simple_dialog_set_cb(dialog, menu_open_recent_file_answered_cb, widget);
1123 /* unchanged file */
1124 menu_open_recent_file_cmd(widget);
1128 /* add the capture filename (with an absolute path) to the "Recent Files" menu */
1130 add_menu_recent_capture_file_absolute(gchar *cf_name) {
1131 GtkWidget *submenu_recent_files;
1132 GList *menu_item_list;
1134 gchar *widget_cf_name;
1135 gchar *normalized_cf_name;
1136 GtkWidget *menu_item;
1141 normalized_cf_name = g_strdup(cf_name);
1143 /* replace all slashes by backslashes */
1144 g_strdelimit(normalized_cf_name, "/", '\\');
1147 /* get the submenu container item */
1148 submenu_recent_files = gtk_item_factory_get_widget(main_menu_factory, MENU_RECENT_FILES_PATH);
1150 /* convert container to a GList */
1151 menu_item_list = gtk_container_children(GTK_CONTAINER(submenu_recent_files));
1153 /* iterate through list items of menu_item_list,
1154 * removing special items, a maybe duplicate entry and every item above count_max */
1156 for (li = g_list_first(menu_item_list); li; li = li->next, cnt++) {
1157 /* get capture filename */
1158 menu_item = GTK_WIDGET(li->data);
1159 widget_cf_name = OBJECT_GET_DATA(menu_item, MENU_RECENT_FILES_KEY);
1161 /* if this element string is one of our special items (seperator, ...) or
1162 * already in the list or
1163 * this element is above maximum count (too old), remove it */
1164 if (!widget_cf_name ||
1166 /* do a case insensitive compare on win32 */
1167 #if GLIB_MAJOR_VERSION < 2
1168 g_strncasecmp(widget_cf_name, normalized_cf_name, 1000) == 0 ||
1170 g_ascii_strncasecmp(widget_cf_name, normalized_cf_name, 1000) == 0 ||
1173 /* do a case sensitive compare on unix */
1174 strncmp(widget_cf_name, normalized_cf_name, 1000) == 0 ||
1176 cnt >= prefs.gui_recent_files_count_max) {
1177 remove_menu_recent_capture_file(li->data, NULL);
1182 g_list_free(menu_item_list);
1184 /* add new item at latest position */
1185 menu_item = gtk_menu_item_new_with_label(normalized_cf_name);
1186 OBJECT_SET_DATA(menu_item, MENU_RECENT_FILES_KEY, normalized_cf_name);
1187 gtk_menu_prepend (GTK_MENU(submenu_recent_files), menu_item);
1188 SIGNAL_CONNECT_OBJECT(GTK_OBJECT(menu_item), "activate",
1189 menu_open_recent_file_cmd_cb, (GtkObject *) menu_item);
1190 gtk_widget_show (menu_item);
1192 /* add seperator at last position */
1193 menu_item = gtk_menu_item_new();
1194 gtk_menu_append (GTK_MENU(submenu_recent_files), menu_item);
1195 gtk_widget_show (menu_item);
1197 /* add new "clear list" item at last position */
1198 #if GTK_MAJOR_VERSION < 2
1199 menu_item = gtk_menu_item_new_with_label("<Clear File List>");
1201 menu_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_CLEAR, NULL);
1203 gtk_menu_append (GTK_MENU(submenu_recent_files), menu_item);
1204 SIGNAL_CONNECT_OBJECT(GTK_OBJECT(menu_item), "activate",
1205 clear_menu_recent_capture_file_cmd_cb, (GtkObject *) menu_item);
1206 gtk_widget_show (menu_item);
1208 update_menu_recent_capture_file(submenu_recent_files);
1212 /* add the capture filename to the "Recent Files" menu */
1213 /* (will change nothing, if this filename is already in the menu) */
1215 add_menu_recent_capture_file(gchar *cf_name) {
1220 /* if this filename is an absolute path, we can use it directly */
1221 if (g_path_is_absolute(cf_name)) {
1222 add_menu_recent_capture_file_absolute(cf_name);
1226 /* this filename is not an absolute path, prepend the current dir */
1227 curr = g_get_current_dir();
1228 absolute = g_strdup_printf("%s%s%s", curr, G_DIR_SEPARATOR_S, cf_name);
1229 add_menu_recent_capture_file_absolute(absolute);
1235 /* write all capture filenames of the menu to the user's recent file */
1237 menu_recent_file_write_all(FILE *rf) {
1238 GtkWidget *submenu_recent_files;
1244 submenu_recent_files = gtk_item_factory_get_widget(main_menu_factory, MENU_RECENT_FILES_PATH);
1246 /* we have to iterate backwards through the children's list,
1247 * so we get the latest item last in the file.
1248 * (don't use gtk_container_foreach() here, it will return the wrong iteration order) */
1249 children = gtk_container_children(GTK_CONTAINER(submenu_recent_files));
1250 child = g_list_last(children);
1251 while(child != NULL) {
1252 /* get capture filename from the menu item label */
1253 cf_name = OBJECT_GET_DATA(child->data, MENU_RECENT_FILES_KEY);
1255 fprintf (rf, RECENT_KEY_CAPTURE_FILE ": %s\n", cf_name);
1258 child = g_list_previous(child);
1261 g_list_free(children);
1266 main_toolbar_show_cb(GtkWidget *w _U_, gpointer d _U_)
1269 /* save current setting in recent */
1270 recent.main_toolbar_show = GTK_CHECK_MENU_ITEM(w)->active;
1272 main_widgets_show_or_hide();
1277 filter_toolbar_show_cb(GtkWidget *w _U_, gpointer d _U_)
1280 /* save current setting in recent */
1281 recent.filter_toolbar_show = GTK_CHECK_MENU_ITEM(w)->active;
1283 main_widgets_show_or_hide();
1288 packet_list_show_cb(GtkWidget *w _U_, gpointer d _U_)
1291 /* save current setting in recent */
1292 recent.packet_list_show = GTK_CHECK_MENU_ITEM(w)->active;
1294 main_widgets_show_or_hide();
1299 tree_view_show_cb(GtkWidget *w _U_, gpointer d _U_)
1302 /* save current setting in recent */
1303 recent.tree_view_show = GTK_CHECK_MENU_ITEM(w)->active;
1305 main_widgets_show_or_hide();
1310 byte_view_show_cb(GtkWidget *w _U_, gpointer d _U_)
1313 /* save current setting in recent */
1314 recent.byte_view_show = GTK_CHECK_MENU_ITEM(w)->active;
1316 main_widgets_show_or_hide();
1321 statusbar_show_cb(GtkWidget *w _U_, gpointer d _U_)
1324 /* save current setting in recent */
1325 recent.statusbar_show = GTK_CHECK_MENU_ITEM(w)->active;
1327 main_widgets_show_or_hide();
1332 timestamp_absolute_cb(GtkWidget *w _U_, gpointer d _U_)
1334 if (recent.gui_time_format != TS_ABSOLUTE) {
1335 timestamp_set_type(TS_ABSOLUTE);
1336 recent.gui_time_format = TS_ABSOLUTE;
1337 cf_change_time_formats(&cfile);
1342 timestamp_absolute_date_cb(GtkWidget *w _U_, gpointer d _U_)
1344 if (recent.gui_time_format != TS_ABSOLUTE_WITH_DATE) {
1345 timestamp_set_type(TS_ABSOLUTE_WITH_DATE);
1346 recent.gui_time_format = TS_ABSOLUTE_WITH_DATE;
1347 cf_change_time_formats(&cfile);
1352 timestamp_relative_cb(GtkWidget *w _U_, gpointer d _U_)
1354 if (recent.gui_time_format != TS_RELATIVE) {
1355 timestamp_set_type(TS_RELATIVE);
1356 recent.gui_time_format = TS_RELATIVE;
1357 cf_change_time_formats(&cfile);
1362 timestamp_delta_cb(GtkWidget *w _U_, gpointer d _U_)
1364 if (recent.gui_time_format != TS_DELTA) {
1365 timestamp_set_type(TS_DELTA);
1366 recent.gui_time_format = TS_DELTA;
1367 cf_change_time_formats(&cfile);
1372 timestamp_auto_cb(GtkWidget *w _U_, gpointer d _U_)
1374 if (recent.gui_time_precision != TS_PREC_AUTO) {
1375 /* the actual precision will be set in cf_change_time_formats() below */
1376 timestamp_set_precision(TS_PREC_AUTO_SEC);
1377 recent.gui_time_precision = TS_PREC_AUTO;
1378 cf_change_time_formats(&cfile);
1383 timestamp_sec_cb(GtkWidget *w _U_, gpointer d _U_)
1385 if (recent.gui_time_precision != TS_PREC_FIXED_SEC) {
1386 timestamp_set_precision(TS_PREC_FIXED_SEC);
1387 recent.gui_time_precision = TS_PREC_FIXED_SEC;
1388 cf_change_time_formats(&cfile);
1393 timestamp_dsec_cb(GtkWidget *w _U_, gpointer d _U_)
1395 if (recent.gui_time_precision != TS_PREC_FIXED_DSEC) {
1396 timestamp_set_precision(TS_PREC_FIXED_DSEC);
1397 recent.gui_time_precision = TS_PREC_FIXED_DSEC;
1398 cf_change_time_formats(&cfile);
1403 timestamp_csec_cb(GtkWidget *w _U_, gpointer d _U_)
1405 if (recent.gui_time_precision != TS_PREC_FIXED_CSEC) {
1406 timestamp_set_precision(TS_PREC_FIXED_CSEC);
1407 recent.gui_time_precision = TS_PREC_FIXED_CSEC;
1408 cf_change_time_formats(&cfile);
1413 timestamp_msec_cb(GtkWidget *w _U_, gpointer d _U_)
1415 if (recent.gui_time_precision != TS_PREC_FIXED_MSEC) {
1416 timestamp_set_precision(TS_PREC_FIXED_MSEC);
1417 recent.gui_time_precision = TS_PREC_FIXED_MSEC;
1418 cf_change_time_formats(&cfile);
1423 timestamp_usec_cb(GtkWidget *w _U_, gpointer d _U_)
1425 if (recent.gui_time_precision != TS_PREC_FIXED_USEC) {
1426 timestamp_set_precision(TS_PREC_FIXED_USEC);
1427 recent.gui_time_precision = TS_PREC_FIXED_USEC;
1428 cf_change_time_formats(&cfile);
1433 timestamp_nsec_cb(GtkWidget *w _U_, gpointer d _U_)
1435 if (recent.gui_time_precision != TS_PREC_FIXED_NSEC) {
1436 timestamp_set_precision(TS_PREC_FIXED_NSEC);
1437 recent.gui_time_precision = TS_PREC_FIXED_NSEC;
1438 cf_change_time_formats(&cfile);
1444 menu_name_resolution_changed(void)
1446 GtkWidget *menu = NULL;
1448 menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Name Resolution/Enable for MAC Layer");
1449 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), g_resolv_flags & RESOLV_MAC);
1451 menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Name Resolution/Enable for Network Layer");
1452 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), g_resolv_flags & RESOLV_NETWORK);
1454 menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Name Resolution/Enable for Transport Layer");
1455 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), g_resolv_flags & RESOLV_TRANSPORT);
1459 name_resolution_mac_cb(GtkWidget *w _U_, gpointer d _U_)
1461 if (GTK_CHECK_MENU_ITEM(w)->active) {
1462 g_resolv_flags |= RESOLV_MAC;
1464 g_resolv_flags &= ~RESOLV_MAC;
1469 name_resolution_network_cb(GtkWidget *w _U_, gpointer d _U_)
1471 if (GTK_CHECK_MENU_ITEM(w)->active) {
1472 g_resolv_flags |= RESOLV_NETWORK;
1474 g_resolv_flags &= ~RESOLV_NETWORK;
1479 name_resolution_transport_cb(GtkWidget *w _U_, gpointer d _U_)
1481 if (GTK_CHECK_MENU_ITEM(w)->active) {
1482 g_resolv_flags |= RESOLV_TRANSPORT;
1484 g_resolv_flags &= ~RESOLV_TRANSPORT;
1490 menu_auto_scroll_live_changed(gboolean auto_scroll_live_in) {
1494 /* tell menu about it */
1495 menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Auto Scroll in Live Capture");
1496 if( ((gboolean) GTK_CHECK_MENU_ITEM(menu)->active) != auto_scroll_live_in) {
1497 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), auto_scroll_live_in);
1500 /* tell toolbar about it */
1501 toolbar_auto_scroll_live_changed(auto_scroll_live_in);
1503 /* change auto scroll */
1504 if(auto_scroll_live_in != auto_scroll_live) {
1505 auto_scroll_live = auto_scroll_live_in;
1510 auto_scroll_live_cb(GtkWidget *w _U_, gpointer d _U_)
1512 menu_auto_scroll_live_changed(GTK_CHECK_MENU_ITEM(w)->active);
1518 menu_colorize_changed(gboolean packet_list_colorize) {
1522 /* tell menu about it */
1523 menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Colorize Packet List");
1524 if( ((gboolean) GTK_CHECK_MENU_ITEM(menu)->active) != packet_list_colorize) {
1525 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), packet_list_colorize);
1528 /* tell toolbar about it */
1529 toolbar_colorize_changed(packet_list_colorize);
1531 /* change colorization */
1532 if(packet_list_colorize != recent.packet_list_colorize) {
1533 recent.packet_list_colorize = packet_list_colorize;
1534 color_filters_enable(packet_list_colorize);
1535 cf_colorize_packets(&cfile);
1540 colorize_cb(GtkWidget *w, gpointer d _U_)
1542 menu_colorize_changed(GTK_CHECK_MENU_ITEM(w)->active);
1546 /* the recent file read has finished, update the menu corresponding */
1548 menu_recent_read_finished(void) {
1549 GtkWidget *menu = NULL;
1551 menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Main Toolbar");
1552 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), recent.main_toolbar_show);
1554 menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Filter Toolbar");
1555 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), recent.filter_toolbar_show);
1557 menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Statusbar");
1558 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), recent.statusbar_show);
1560 menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Packet List");
1561 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), recent.packet_list_show);
1563 menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Packet Details");
1564 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), recent.tree_view_show);
1566 menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Packet Bytes");
1567 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), recent.byte_view_show);
1569 menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Colorize Packet List");
1570 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), recent.packet_list_colorize);
1572 menu_name_resolution_changed();
1575 menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Auto Scroll in Live Capture");
1576 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), auto_scroll_live);
1579 main_widgets_rearrange();
1581 /* don't change the time format, if we had a command line value */
1582 if (timestamp_get_type() != TS_NOT_SET) {
1583 recent.gui_time_format = timestamp_get_type();
1586 switch(recent.gui_time_format) {
1587 case(TS_ABSOLUTE_WITH_DATE):
1588 menu = gtk_item_factory_get_widget(main_menu_factory,
1589 "/View/Time Display Format/Date and Time of Day: 1970-01-01 01:02:03.123456");
1590 /* set_active will not trigger the callback when activating an active item! */
1591 recent.gui_time_format = -1;
1592 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), FALSE);
1593 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE);
1596 menu = gtk_item_factory_get_widget(main_menu_factory,
1597 "/View/Time Display Format/Time of Day: 01:02:03.123456");
1598 /* set_active will not trigger the callback when activating an active item! */
1599 recent.gui_time_format = -1;
1600 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE);
1603 menu = gtk_item_factory_get_widget(main_menu_factory,
1604 "/View/Time Display Format/Seconds Since Beginning of Capture: 123.123456");
1605 recent.gui_time_format = -1;
1606 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE);
1609 menu = gtk_item_factory_get_widget(main_menu_factory,
1610 "/View/Time Display Format/Seconds Since Previous Packet: 1.123456");
1611 recent.gui_time_format = -1;
1612 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE);
1615 g_assert_not_reached();
1618 switch(recent.gui_time_precision) {
1620 menu = gtk_item_factory_get_widget(main_menu_factory,
1621 "/View/Time Display Format/Automatic (File Format Precision)");
1622 /* set_active will not trigger the callback when activating an active item! */
1623 recent.gui_time_precision = -1;
1624 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), FALSE);
1625 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE);
1627 case(TS_PREC_FIXED_SEC):
1628 menu = gtk_item_factory_get_widget(main_menu_factory,
1629 "/View/Time Display Format/Seconds: 0");
1630 recent.gui_time_precision = -1;
1631 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE);
1633 case(TS_PREC_FIXED_DSEC):
1634 menu = gtk_item_factory_get_widget(main_menu_factory,
1635 "/View/Time Display Format/Deciseconds: 0.1");
1636 recent.gui_time_precision = -1;
1637 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE);
1639 case(TS_PREC_FIXED_CSEC):
1640 menu = gtk_item_factory_get_widget(main_menu_factory,
1641 "/View/Time Display Format/Centiseconds: 0.12");
1642 recent.gui_time_precision = -1;
1643 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE);
1645 case(TS_PREC_FIXED_MSEC):
1646 menu = gtk_item_factory_get_widget(main_menu_factory,
1647 "/View/Time Display Format/Milliseconds: 0.123");
1648 recent.gui_time_precision = -1;
1649 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE);
1651 case(TS_PREC_FIXED_USEC):
1652 menu = gtk_item_factory_get_widget(main_menu_factory,
1653 "/View/Time Display Format/Microseconds: 0.123456");
1654 recent.gui_time_precision = -1;
1655 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE);
1657 case(TS_PREC_FIXED_NSEC):
1658 menu = gtk_item_factory_get_widget(main_menu_factory,
1659 "/View/Time Display Format/Nanoseconds: 0.123456789");
1660 recent.gui_time_precision = -1;
1661 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE);
1664 g_assert_not_reached();
1667 menu_colorize_changed(recent.packet_list_colorize);
1672 popup_menu_handler(GtkWidget *widget, GdkEvent *event, gpointer data)
1674 GtkWidget *menu = (GtkWidget *)data;
1675 GdkEventButton *event_button = NULL;
1678 if(widget == NULL || event == NULL || data == NULL) {
1683 * If we ever want to make the menu differ based on what row
1684 * and/or column we're above, we'd use "eth_clist_get_selection_info()"
1685 * to find the row and column number for the coordinates; a CTree is,
1686 * I guess, like a CList with one column(?) and the expander widget
1689 /* Check if we are on packet_list object */
1690 if (widget == OBJECT_GET_DATA(popup_menu_object, E_MPACKET_LIST_KEY)) {
1691 if (packet_list_get_event_row_column(widget, (GdkEventButton *)event,
1693 OBJECT_SET_DATA(popup_menu_object, E_MPACKET_LIST_ROW_KEY,
1694 GINT_TO_POINTER(row));
1695 OBJECT_SET_DATA(popup_menu_object, E_MPACKET_LIST_COL_KEY,
1696 GINT_TO_POINTER(column));
1697 packet_list_set_selected_row(row);
1701 /* Check if we are on tree_view object */
1702 if (widget == tree_view) {
1703 tree_view_select(widget, (GdkEventButton *) event);
1706 /* Check if we are on byte_view object */
1707 if(widget == get_notebook_bv_ptr(byte_nb_ptr)) {
1708 byte_view_select(widget, (GdkEventButton *) event);
1711 /* context menu handler (but the byte view notebook pages have their own handler) */
1712 if(event->type == GDK_BUTTON_PRESS && widget != byte_nb_ptr) {
1713 event_button = (GdkEventButton *) event;
1715 /* To qoute the "Gdk Event Structures" doc:
1716 * "Normally button 1 is the left mouse button, 2 is the middle button, and 3 is the right button" */
1717 if(event_button->button == 3) {
1718 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
1719 event_button->button,
1720 event_button->time);
1721 SIGNAL_EMIT_STOP_BY_NAME(widget, "button_press_event");
1725 #if GTK_MAJOR_VERSION >= 2
1726 /* GDK_2BUTTON_PRESS is a doubleclick -> expand/collapse tree row */
1727 /* GTK version 1 seems to be doing this automatically */
1728 if (widget == tree_view && event->type == GDK_2BUTTON_PRESS) {
1731 if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget),
1732 (gint) (((GdkEventButton *)event)->x),
1733 (gint) (((GdkEventButton *)event)->y),
1734 &path, NULL, NULL, NULL))
1736 if (gtk_tree_view_row_expanded(GTK_TREE_VIEW(widget), path))
1737 gtk_tree_view_collapse_row(GTK_TREE_VIEW(widget), path);
1739 gtk_tree_view_expand_row(GTK_TREE_VIEW(widget), path,
1741 gtk_tree_path_free(path);
1748 /* Enable or disable menu items based on whether you have a capture file
1749 you've finished reading. */
1751 set_menus_for_capture_file(gboolean have_capture_file)
1753 set_menu_sensitivity(main_menu_factory, "/File/Open...", have_capture_file);
1754 set_menu_sensitivity(main_menu_factory, "/File/Open Recent", have_capture_file);
1755 set_menu_sensitivity(main_menu_factory, "/File/Merge...", have_capture_file);
1756 set_menu_sensitivity(main_menu_factory, "/File/Close", have_capture_file);
1757 set_menu_sensitivity(main_menu_factory, "/File/Save As...",
1759 set_menu_sensitivity(main_menu_factory, "/File/Export", have_capture_file);
1760 set_menu_sensitivity(main_menu_factory, "/View/Reload", have_capture_file);
1761 set_toolbar_for_capture_file(have_capture_file);
1762 packets_bar_update();
1765 /* Enable or disable menu items based on whether you have an unsaved
1766 capture file you've finished reading. */
1768 set_menus_for_unsaved_capture_file(gboolean have_unsaved_capture_file)
1770 set_menu_sensitivity(main_menu_factory, "/File/Save",
1771 have_unsaved_capture_file);
1772 set_toolbar_for_unsaved_capture_file(have_unsaved_capture_file);
1775 /* Enable or disable menu items based on whether there's a capture in
1778 set_menus_for_capture_in_progress(gboolean capture_in_progress)
1780 set_menu_sensitivity(main_menu_factory, "/File/Open...",
1781 !capture_in_progress);
1782 set_menu_sensitivity(main_menu_factory, "/File/Open Recent",
1783 !capture_in_progress);
1785 set_menu_sensitivity(main_menu_factory, "/Capture/Options...",
1786 !capture_in_progress);
1787 set_menu_sensitivity(main_menu_factory, "/Capture/Start",
1788 !capture_in_progress);
1789 set_menu_sensitivity(main_menu_factory, "/Capture/Stop",
1790 capture_in_progress);
1791 set_menu_sensitivity(main_menu_factory, "/Capture/Restart",
1792 capture_in_progress);
1793 set_toolbar_for_capture_in_progress(capture_in_progress);
1795 set_capture_if_dialog_for_capture_in_progress(capture_in_progress);
1796 #endif /* HAVE_LIBPCAP */
1799 /* Enable or disable menu items based on whether you have some captured
1802 walk_menu_tree_for_captured_packets(GList *node,
1803 gboolean have_captured_packets)
1805 gboolean is_enabled;
1807 menu_item_t *node_data = node->data;
1810 * Is this a leaf node or an interior node?
1812 if (node_data->children == NULL) {
1816 * If it has no "selected_packet_enabled()" or
1817 * "selected_tree_row_enabled()" routines, we enable
1818 * it. This allows tap windows to be popped up even
1819 * if you have no capture file; this is done to let
1820 * the user pop up multiple tap windows before reading
1821 * in a capture file, so that they can be processed in
1822 * parallel while the capture file is being read rather
1823 * than one at at time as you pop up the windows, and to
1824 * let the user pop up tap windows before starting an
1825 * "Update list of packets in real time" capture, so that
1826 * the statistics can be displayed while the capture is
1829 * If it has either of those routines, we disable it for
1830 * now - as long as, when a capture is first available,
1831 * we don't get called after a packet or tree row is
1832 * selected, that's OK.
1833 * XXX - that should be done better.
1835 if (node_data->selected_packet_enabled == NULL &&
1836 node_data->selected_tree_row_enabled == NULL)
1837 node_data->enabled = TRUE;
1839 node_data->enabled = FALSE;
1842 * It's an interior node; call
1843 * "walk_menu_tree_for_captured_packets()" on all its
1844 * children and, if any of them are enabled, enable
1845 * this node, otherwise disable it.
1847 * XXX - should we just leave all interior nodes enabled?
1848 * Which is a better UI choice?
1851 for (child = node_data->children; child != NULL; child =
1853 if (walk_menu_tree_for_captured_packets(child,
1854 have_captured_packets))
1857 node_data->enabled = is_enabled;
1861 * The root node doesn't correspond to a menu tree item; it
1862 * has a null name pointer.
1864 if (node_data->name != NULL) {
1865 set_menu_sensitivity(main_menu_factory, node_data->name,
1866 node_data->enabled);
1868 return node_data->enabled;
1872 set_menus_for_captured_packets(gboolean have_captured_packets)
1874 set_menu_sensitivity(main_menu_factory, "/File/Print...",
1875 have_captured_packets);
1876 set_menu_sensitivity(packet_list_menu_factory, "/Print...",
1877 have_captured_packets);
1878 set_menu_sensitivity(main_menu_factory, "/Edit/Find Packet...",
1879 have_captured_packets);
1880 set_menu_sensitivity(main_menu_factory, "/Edit/Find Next",
1881 have_captured_packets);
1882 set_menu_sensitivity(main_menu_factory, "/Edit/Find Previous",
1883 have_captured_packets);
1884 set_menu_sensitivity(main_menu_factory, "/View/Zoom In",
1885 have_captured_packets);
1886 set_menu_sensitivity(main_menu_factory, "/View/Zoom Out",
1887 have_captured_packets);
1888 set_menu_sensitivity(main_menu_factory, "/View/Normal Size",
1889 have_captured_packets);
1890 set_menu_sensitivity(main_menu_factory, "/Go/Go to Packet...",
1891 have_captured_packets);
1892 set_menu_sensitivity(main_menu_factory, "/Go/First Packet",
1893 have_captured_packets);
1894 set_menu_sensitivity(main_menu_factory, "/Go/Last Packet",
1895 have_captured_packets);
1896 set_menu_sensitivity(main_menu_factory, "/Statistics/Summary",
1897 have_captured_packets);
1898 set_menu_sensitivity(main_menu_factory, "/Statistics/Protocol Hierarchy",
1899 have_captured_packets);
1901 walk_menu_tree_for_captured_packets(tap_menu_tree_root,
1902 have_captured_packets);
1903 set_toolbar_for_captured_packets(have_captured_packets);
1904 packets_bar_update();
1907 /* Enable or disable menu items based on whether a packet is selected and,
1908 if so, on the properties of the packet. */
1910 walk_menu_tree_for_selected_packet(GList *node, frame_data *fd,
1911 epan_dissect_t *edt)
1913 gboolean is_enabled;
1915 menu_item_t *node_data = node->data;
1918 * Is this a leaf node or an interior node?
1920 if (node_data->children == NULL) {
1924 * If it has no "selected_packet_enabled()" routine,
1925 * leave its enabled/disabled status alone - it
1926 * doesn't depend on whether we have a packet selected
1927 * or not or on the selected packet.
1929 * If it has a "selected_packet_enabled()" routine,
1930 * call it and set the item's enabled/disabled status
1931 * based on its return value.
1933 if (node_data->selected_packet_enabled != NULL)
1934 node_data->enabled = node_data->selected_packet_enabled(fd, edt);
1937 * It's an interior node; call
1938 * "walk_menu_tree_for_selected_packet()" on all its
1939 * children and, if any of them are enabled, enable
1940 * this node, otherwise disable it.
1942 * XXX - should we just leave all interior nodes enabled?
1943 * Which is a better UI choice?
1946 for (child = node_data->children; child != NULL; child =
1948 if (walk_menu_tree_for_selected_packet(child, fd, edt))
1951 node_data->enabled = is_enabled;
1955 * The root node doesn't correspond to a menu tree item; it
1956 * has a null name pointer.
1958 if (node_data->name != NULL) {
1959 set_menu_sensitivity(main_menu_factory, node_data->name,
1960 node_data->enabled);
1962 return node_data->enabled;
1966 packet_is_ssl(epan_dissect_t* edt)
1970 if (!edt || !edt->tree)
1972 ssl_id = proto_get_id_by_filter_name("ssl");
1975 array = proto_find_finfo(edt->tree, ssl_id);
1976 is_ssl = array->len > 0;
1977 g_ptr_array_free(array, FALSE);
1982 set_menus_for_selected_packet(capture_file *cf)
1984 int is_ssl = packet_is_ssl(cf->edt);
1985 set_menu_sensitivity(main_menu_factory, "/Edit/Mark Packet (toggle)",
1986 cf->current_frame != NULL);
1987 set_menu_sensitivity(packet_list_menu_factory, "/Mark Packet (toggle)",
1988 cf->current_frame != NULL);
1989 set_menu_sensitivity(main_menu_factory, "/Edit/Time Reference",
1990 cf->current_frame != NULL);
1991 set_menu_sensitivity(packet_list_menu_factory, "/Time Reference",
1992 cf->current_frame != NULL);
1993 set_menu_sensitivity(main_menu_factory, "/Edit/Mark All Packets",
1994 cf->current_frame != NULL);
1995 set_menu_sensitivity(main_menu_factory, "/Edit/Unmark All Packets",
1996 cf->current_frame != NULL);
1997 set_menu_sensitivity(main_menu_factory, "/View/Resize All Columns",
1998 cf->current_frame != NULL);
1999 set_menu_sensitivity(main_menu_factory, "/View/Collapse All",
2000 cf->current_frame != NULL);
2001 set_menu_sensitivity(tree_view_menu_factory, "/Collapse All",
2002 cf->current_frame != NULL);
2003 set_menu_sensitivity(main_menu_factory, "/View/Expand All",
2004 cf->current_frame != NULL);
2005 set_menu_sensitivity(tree_view_menu_factory, "/Expand All",
2006 cf->current_frame != NULL);
2007 set_menu_sensitivity(main_menu_factory, "/View/Show Packet in New Window",
2008 cf->current_frame != NULL);
2009 set_menu_sensitivity(packet_list_menu_factory, "/Show Packet in New Window",
2010 cf->current_frame != NULL);
2011 set_menu_sensitivity(main_menu_factory, "/Analyze/Follow TCP Stream",
2012 cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_TCP) : FALSE);
2013 set_menu_sensitivity(packet_list_menu_factory, "/Follow TCP Stream",
2014 cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_TCP) : FALSE);
2015 set_menu_sensitivity(tree_view_menu_factory, "/Follow TCP Stream",
2016 cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_TCP) : FALSE);
2017 set_menu_sensitivity(main_menu_factory, "/Analyze/Follow SSL Stream",
2018 cf->current_frame != NULL ? is_ssl : FALSE);
2019 set_menu_sensitivity(packet_list_menu_factory, "/Follow SSL Stream",
2020 cf->current_frame != NULL ? is_ssl : FALSE);
2021 set_menu_sensitivity(tree_view_menu_factory, "/Follow SSL Stream",
2022 cf->current_frame != NULL ? is_ssl : FALSE);
2023 set_menu_sensitivity(main_menu_factory, "/Analyze/Decode As...",
2024 cf->current_frame != NULL && decode_as_ok());
2025 set_menu_sensitivity(packet_list_menu_factory, "/Decode As...",
2026 cf->current_frame != NULL && decode_as_ok());
2027 set_menu_sensitivity(tree_view_menu_factory, "/Decode As...",
2028 cf->current_frame != NULL && decode_as_ok());
2029 set_menu_sensitivity(main_menu_factory, "/View/Name Resolution/Resolve Name",
2030 cf->current_frame != NULL && (g_resolv_flags & RESOLV_ALL_ADDRS) != RESOLV_ALL_ADDRS);
2031 set_menu_sensitivity(tree_view_menu_factory, "/Resolve Name",
2032 cf->current_frame != NULL && (g_resolv_flags & RESOLV_ALL_ADDRS) != RESOLV_ALL_ADDRS);
2033 set_menu_sensitivity(packet_list_menu_factory, "/Apply as Filter",
2034 cf->current_frame != NULL);
2035 set_menu_sensitivity(packet_list_menu_factory, "/Prepare a Filter",
2036 cf->current_frame != NULL);
2038 walk_menu_tree_for_selected_packet(tap_menu_tree_root, cf->current_frame,
2040 packets_bar_update();
2043 /* Enable or disable menu items based on whether a tree row is selected
2044 and, if so, on the properties of the tree row. */
2046 walk_menu_tree_for_selected_tree_row(GList *node, field_info *fi)
2048 gboolean is_enabled;
2050 menu_item_t *node_data = node->data;
2053 * Is this a leaf node or an interior node?
2055 if (node_data->children == NULL) {
2059 * If it has no "selected_tree_row_enabled()" routine,
2060 * leave its enabled/disabled status alone - it
2061 * doesn't depend on whether we have a tree row selected
2062 * or not or on the selected tree row.
2064 * If it has a "selected_tree_row_enabled()" routine,
2065 * call it and set the item's enabled/disabled status
2066 * based on its return value.
2068 if (node_data->selected_tree_row_enabled != NULL)
2069 node_data->enabled = node_data->selected_tree_row_enabled(fi);
2072 * It's an interior node; call
2073 * "walk_menu_tree_for_selected_tree_row()" on all its
2074 * children and, if any of them are enabled, enable
2075 * this node, otherwise disable it.
2077 * XXX - should we just leave all interior nodes enabled?
2078 * Which is a better UI choice?
2081 for (child = node_data->children; child != NULL; child =
2083 if (walk_menu_tree_for_selected_tree_row(child, fi))
2086 node_data->enabled = is_enabled;
2090 * The root node doesn't correspond to a menu tree item; it
2091 * has a null name pointer.
2093 if (node_data->name != NULL) {
2094 set_menu_sensitivity(main_menu_factory, node_data->name,
2095 node_data->enabled);
2097 return node_data->enabled;
2101 set_menus_for_selected_tree_row(capture_file *cf)
2103 gboolean properties;
2106 set_menu_sensitivity(main_menu_factory, "/File/Export/Selected Packet Bytes...",
2107 cf->finfo_selected != NULL);
2108 set_menu_sensitivity(hexdump_menu_factory, "/Copy",
2109 cf->finfo_selected != NULL);
2110 set_menu_sensitivity(hexdump_menu_factory, "/Export Selected Packet Bytes...",
2111 cf->finfo_selected != NULL);
2113 if (cf->finfo_selected != NULL) {
2114 header_field_info *hfinfo = cf->finfo_selected->hfinfo;
2115 if (hfinfo->parent == -1) {
2116 properties = prefs_is_registered_protocol(hfinfo->abbrev);
2118 properties = prefs_is_registered_protocol(proto_registrar_get_abbrev(hfinfo->parent));
2120 set_menu_sensitivity(main_menu_factory,
2121 "/Go/Go to Corresponding Packet", hfinfo->type == FT_FRAMENUM);
2122 set_menu_sensitivity(tree_view_menu_factory,
2123 "/Go to Corresponding Packet", hfinfo->type == FT_FRAMENUM);
2124 set_menu_sensitivity(main_menu_factory, "/Analyze/Apply as Filter",
2125 proto_can_match_selected(cf->finfo_selected, cf->edt));
2126 set_menu_sensitivity(tree_view_menu_factory, "/Apply as Filter",
2127 proto_can_match_selected(cf->finfo_selected, cf->edt));
2128 set_menu_sensitivity(main_menu_factory, "/Analyze/Prepare a Filter",
2129 proto_can_match_selected(cf->finfo_selected, cf->edt));
2130 set_menu_sensitivity(tree_view_menu_factory, "/Prepare a Filter",
2131 proto_can_match_selected(cf->finfo_selected, cf->edt));
2132 set_menu_sensitivity(tree_view_menu_factory, "/Protocol Preferences...",
2134 set_menu_sensitivity(main_menu_factory, "/View/Expand Subtrees", cf->finfo_selected->tree_type != -1);
2135 set_menu_sensitivity(tree_view_menu_factory, "/Expand Subtrees", cf->finfo_selected->tree_type != -1);
2136 set_menu_sensitivity(tree_view_menu_factory, "/Wiki Protocol Page",
2138 set_menu_sensitivity(tree_view_menu_factory, "/Filter Field Reference",
2140 set_menu_sensitivity(tree_view_menu_factory, "/Field Information",
2141 selected_ptree_has_field_url());
2143 set_menu_sensitivity(main_menu_factory,
2144 "/Go/Go to Corresponding Packet", FALSE);
2145 set_menu_sensitivity(tree_view_menu_factory,
2146 "/Go to Corresponding Packet", FALSE);
2147 set_menu_sensitivity(main_menu_factory, "/Analyze/Apply as Filter", FALSE);
2148 set_menu_sensitivity(tree_view_menu_factory, "/Apply as Filter", FALSE);
2149 set_menu_sensitivity(main_menu_factory, "/Analyze/Prepare a Filter", FALSE);
2150 set_menu_sensitivity(tree_view_menu_factory, "/Prepare a Filter", FALSE);
2151 set_menu_sensitivity(tree_view_menu_factory, "/Protocol Preferences...",
2153 set_menu_sensitivity(main_menu_factory, "/View/Expand Subtrees", FALSE);
2154 set_menu_sensitivity(tree_view_menu_factory, "/Expand Subtrees", FALSE);
2155 set_menu_sensitivity(tree_view_menu_factory, "/Wiki Protocol Page",
2157 set_menu_sensitivity(tree_view_menu_factory, "/Filter Field Reference",
2159 set_menu_sensitivity(tree_view_menu_factory, "/Field Information",
2163 walk_menu_tree_for_selected_tree_row(tap_menu_tree_root, cf->finfo_selected);
2166 void set_menus_for_packet_history(gboolean back_history, gboolean forward_history) {
2168 set_menu_sensitivity(main_menu_factory, "/Go/Back", back_history);
2169 set_menu_sensitivity(main_menu_factory, "/Go/Forward", forward_history);
2171 set_toolbar_for_packet_history(back_history, forward_history);
2175 void set_menus_for_file_set(gboolean file_set, gboolean previous_file, gboolean next_file) {
2177 set_menu_sensitivity(main_menu_factory, "/File/File Set/List Files", file_set);
2178 set_menu_sensitivity(main_menu_factory, "/File/File Set/Previous File", previous_file);
2179 set_menu_sensitivity(main_menu_factory, "/File/File Set/Next File", next_file);