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"
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_ENTRY("/Protocol Preferences...", NULL, properties_cb,
524 ITEM_FACTORY_ENTRY("/<separator>", NULL, NULL, 0, "<Separator>", NULL),
525 ITEM_FACTORY_STOCK_ENTRY("/Decode As...", NULL, decode_as_cb, 0, ETHEREAL_STOCK_DECODE_AS),
526 ITEM_FACTORY_ENTRY("/_Resolve Name", NULL, resolve_name_cb, 0, NULL, NULL),
527 ITEM_FACTORY_ENTRY("/_Go to Corresponding Packet", NULL, goto_framenum_cb, 0, NULL, NULL),
530 static GtkItemFactoryEntry hexdump_menu_items[] =
532 ITEM_FACTORY_ENTRY("/Copy", NULL, copy_hex_cb,
534 ITEM_FACTORY_ENTRY("/Export Selected Packet Bytes...", NULL, savehex_cb,
538 static int initialize = TRUE;
539 static GtkItemFactory *main_menu_factory = NULL;
540 static GtkItemFactory *packet_list_menu_factory = NULL;
541 static GtkItemFactory *tree_view_menu_factory = NULL;
542 static GtkItemFactory *hexdump_menu_factory = NULL;
544 static GSList *popup_menu_list = NULL;
546 static GtkAccelGroup *grp;
549 main_menu_new(GtkAccelGroup ** table) {
552 grp = gtk_accel_group_new();
557 menubar = main_menu_factory->widget;
571 packet_list_menu_factory = gtk_item_factory_new(GTK_TYPE_MENU, "<main>", NULL);
572 popup_menu_object = gtk_menu_new();
573 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);
574 OBJECT_SET_DATA(popup_menu_object, PM_PACKET_LIST_KEY,
575 packet_list_menu_factory->widget);
576 popup_menu_list = g_slist_append((GSList *)popup_menu_list, packet_list_menu_factory);
578 tree_view_menu_factory = gtk_item_factory_new(GTK_TYPE_MENU, "<main>", NULL);
579 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);
580 OBJECT_SET_DATA(popup_menu_object, PM_TREE_VIEW_KEY,
581 tree_view_menu_factory->widget);
582 popup_menu_list = g_slist_append((GSList *)popup_menu_list, tree_view_menu_factory);
584 hexdump_menu_factory = gtk_item_factory_new(GTK_TYPE_MENU, "<main>", NULL);
585 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);
586 OBJECT_SET_DATA(popup_menu_object, PM_HEXDUMP_KEY,
587 hexdump_menu_factory->widget);
588 popup_menu_list = g_slist_append((GSList *)popup_menu_list, hexdump_menu_factory);
591 main_menu_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", grp);
592 gtk_item_factory_create_items_ac(main_menu_factory, nmenu_items, menu_items, NULL, 2);
594 merge_all_tap_menus(tap_menu_tree_root);
596 /* Initialize enabled/disabled state of menu items */
597 set_menus_for_unsaved_capture_file(FALSE);
598 set_menus_for_capture_file(FALSE);
600 /* Un-#if this when we actually implement Cut/Copy/Paste.
601 Then make sure you enable them when they can be done. */
602 set_menu_sensitivity(main_menu_factory, "/Edit/Cut", FALSE);
603 set_menu_sensitivity(main_menu_factory, "/Edit/Copy", FALSE);
604 set_menu_sensitivity(main_menu_factory, "/Edit/Paste", FALSE);
607 set_menus_for_captured_packets(FALSE);
608 set_menus_for_selected_packet(&cfile);
609 set_menus_for_selected_tree_row(&cfile);
610 set_menus_for_capture_in_progress(FALSE);
611 set_menus_for_file_set(/* dialog */TRUE, /* previous file */ FALSE, /* next_file */ FALSE);
613 /* init with an empty recent files list */
614 clear_menu_recent_capture_file_cmd_cb(NULL, NULL);
619 static gint tap_menu_item_add_compare(gconstpointer a, gconstpointer b)
622 ((const menu_item_t *) a)->name,
623 ((const menu_item_t *) b)->name);
627 /* add a menuitem below the current node */
628 static GList * tap_menu_item_add(
631 GtkItemFactoryCallback callback,
632 gboolean (*selected_packet_enabled)(frame_data *, epan_dissect_t *),
633 gboolean (*selected_tree_row_enabled)(field_info *),
634 gpointer callback_data,
641 child = g_malloc(sizeof (menu_item_t));
642 child->group = group;
644 child->callback = callback;
645 child->selected_packet_enabled = selected_packet_enabled;
646 child->selected_tree_row_enabled = selected_tree_row_enabled;
647 child->callback_data = callback_data;
648 child->enabled = FALSE;
649 child->children = NULL;
651 /* insert the new child node into the parent */
652 curr = curnode->data;
653 curr->children = g_list_insert_sorted(curr->children, child, tap_menu_item_add_compare);
655 /* return the new node */
656 /* XXX: improve this */
657 return g_list_find(curr->children, child);
661 * Add a new menu item for a tap.
662 * This must be called after we've created the main menu, so it can't
663 * be called from the routine that registers taps - we have to introduce
664 * another per-tap registration routine.
666 * "callback" gets called when the menu item is selected; it should do
667 * the work of creating the tap window.
669 * "selected_packet_enabled" gets called by "set_menus_for_selected_packet()";
670 * it's passed a Boolean that's TRUE if a packet is selected and FALSE
671 * otherwise, and should return TRUE if the tap will work now (which
672 * might depend on whether a packet is selected and, if one is, on the
673 * packet) and FALSE if not.
675 * "selected_tree_row_enabled" gets called by
676 * "set_menus_for_selected_tree_row()"; it's passed a Boolean that's TRUE if
677 * a protocol tree row is selected and FALSE otherwise, and should return
678 * TRUE if the tap will work now (which might depend on whether a tree row
679 * is selected and, if one is, on the tree row) and FALSE if not.
682 register_stat_menu_item(
684 REGISTER_STAT_GROUP_E group,
685 GtkItemFactoryCallback callback,
686 gboolean (*selected_packet_enabled)(frame_data *, epan_dissect_t *),
687 gboolean (*selected_tree_row_enabled)(field_info *),
688 gpointer callback_data)
690 /*static const char toolspath[] = "/Statistics/";*/
691 const char *toolspath;
700 * The menu path must be relative.
702 g_assert(*name != '/');
705 case(REGISTER_STAT_GROUP_GENERIC): toolspath = "/Statistics/"; break;
706 case(REGISTER_STAT_GROUP_CONVERSATION_LIST): toolspath = "/Statistics/_Conversation List/"; break;
707 case(REGISTER_STAT_GROUP_ENDPOINT_LIST): toolspath = "/Statistics/_Endpoint List/"; break;
708 case(REGISTER_STAT_GROUP_RESPONSE_TIME): toolspath = "/Statistics/Service _Response Time/"; break;
709 case(REGISTER_STAT_GROUP_TELEPHONY): toolspath = "/Statistics/"; break;
710 case(REGISTER_STAT_GROUP_NONE): toolspath = "/Statistics/"; break;
711 case(REGISTER_ANALYZE_GROUP_NONE): toolspath = "/Analyze/"; break;
717 /* add the (empty) root node, if not already done */
718 if(tap_menu_tree_root == NULL) {
719 child = g_malloc0(sizeof (menu_item_t));
720 tap_menu_tree_root = g_list_append(NULL, child);
724 * Create any submenus required.
726 curnode = tap_menu_tree_root;
728 while ((p = strchr(p, '/')) != NULL) {
730 * OK, everything between "name" and "p" is
731 * a menu relative subtree into which the menu item
734 * Construct the absolute path name of that subtree.
736 menupathlen = strlen(toolspath) + 1 + (p - name);
737 menupath = g_malloc(menupathlen);
738 strcpy(menupath, toolspath);
739 strncat(menupath, name, p - name);
742 * Does there exist an entry with that path at this
743 * level of the Analyze menu tree?
745 child = curnode->data;
746 for (childnode = child->children; childnode != NULL; childnode = childnode->next) {
747 child = childnode->data;
748 if (strcmp(child->name, menupath) == 0)
751 if (childnode == NULL) {
753 * No. Create such an item as a subtree, and
754 * add it to the Tools menu tree.
756 childnode = tap_menu_item_add(
757 menupath, group, NULL, NULL ,NULL, NULL, curnode);
760 * Yes. We don't need this "menupath" any longer.
767 * Skip over the '/' we found.
773 * Construct the main menu path for the menu item.
775 menupathlen = strlen(toolspath) + 1 + strlen(name);
776 menupath = g_malloc(menupathlen);
777 strcpy(menupath, toolspath);
778 strcat(menupath, name);
781 * Construct an item factory entry for the item, and add it to
785 menupath, group, callback,
786 selected_packet_enabled, selected_tree_row_enabled,
787 callback_data, curnode);
791 static guint merge_tap_menus_layered(GList *node, gint group) {
792 GtkItemFactoryEntry *entry;
795 menu_item_t *node_data = node->data;
798 * Is this a leaf node or an interior node?
800 if (node_data->children == NULL) {
806 * The root node doesn't correspond to a menu tree item; it
807 * has a null name pointer.
809 if (node_data->name != NULL && group == node_data->group) {
810 entry = g_malloc0(sizeof (GtkItemFactoryEntry));
811 entry->path = node_data->name;
812 entry->callback = node_data->callback;
813 #if GTK_MAJOR_VERSION >= 2
815 case(REGISTER_STAT_GROUP_NONE):
817 case(REGISTER_STAT_GROUP_GENERIC):
819 case(REGISTER_STAT_GROUP_CONVERSATION_LIST):
820 entry->item_type = "<StockItem>";
821 entry->extra_data = ETHEREAL_STOCK_CONVERSATIONS;
823 case(REGISTER_STAT_GROUP_ENDPOINT_LIST):
824 entry->item_type = "<StockItem>";
825 entry->extra_data = ETHEREAL_STOCK_ENDPOINTS;
827 case(REGISTER_STAT_GROUP_RESPONSE_TIME):
828 entry->item_type = "<StockItem>";
829 entry->extra_data = ETHEREAL_STOCK_TIME;
831 case(REGISTER_STAT_GROUP_TELEPHONY):
832 entry->item_type = "<StockItem>";
833 entry->extra_data = ETHEREAL_STOCK_TELEPHONY;
835 case(REGISTER_ANALYZE_GROUP_NONE):
838 g_assert_not_reached();
841 gtk_item_factory_create_item(main_menu_factory, entry, node_data->callback_data, 2);
842 set_menu_sensitivity(main_menu_factory, node_data->name, FALSE); /* no capture file yet */
847 * It's an interior node; call
848 * "merge_tap_menus_layered()" on all its children
852 * The root node doesn't correspond to a menu tree item; it
853 * has a null name pointer.
855 if (node_data->name != NULL && group == node_data->group) {
856 entry = g_malloc0(sizeof (GtkItemFactoryEntry));
857 entry->path = node_data->name;
858 entry->item_type = "<Branch>";
859 gtk_item_factory_create_item(main_menu_factory, entry,
861 set_menu_sensitivity(main_menu_factory, node_data->name,
862 FALSE); /* no children yet */
866 for (child = node_data->children; child != NULL; child =
868 added += merge_tap_menus_layered(child, group);
876 void merge_all_tap_menus(GList *node) {
877 GtkItemFactoryEntry *entry;
879 entry = g_malloc0(sizeof (GtkItemFactoryEntry));
880 entry->item_type = "<Separator>";
881 entry->path = "/Statistics/";
884 * merge only the menu items of the specific group,
885 * and then append a seperator
887 if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_GENERIC)) {
888 gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);
890 if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_CONVERSATION_LIST)) {
891 /*gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);*/
893 if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_ENDPOINT_LIST)) {
894 /*gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);*/
896 if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_RESPONSE_TIME)) {
897 gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);
899 if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_TELEPHONY)) {
900 gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);
902 if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_NONE)) {
903 /*gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);*/
905 if (merge_tap_menus_layered(node, REGISTER_ANALYZE_GROUP_NONE)) {
906 entry->path = "/Analyze/";
907 /*gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);*/
914 * Enable/disable menu sensitivity.
917 set_menu_sensitivity(GtkItemFactory *ifactory, const gchar *path, gint val)
920 GtkWidget *menu_item;
925 /* the underscore character regularly confuses things, as it will prevent finding
926 * the menu_item, so it has to be removed first */
927 dup = g_strdup(path);
938 if (ifactory == NULL) {
940 * Do it for all pop-up menus.
942 for (menu_list = popup_menu_list; menu_list != NULL;
943 menu_list = g_slist_next(menu_list))
944 set_menu_sensitivity(menu_list->data, dup, val);
947 * Do it for that particular menu.
949 if ((menu_item = gtk_item_factory_get_widget(ifactory, dup)) != NULL) {
950 if (GTK_IS_MENU(menu_item)) {
952 * "dup" refers to a submenu; "gtk_item_factory_get_widget()"
953 * gets the menu, not the item that, when selected, pops up
956 * We have to change the latter item's sensitivity, so that
957 * it shows up normally if sensitive and grayed-out if
960 menu_item = gtk_menu_get_attach_widget(GTK_MENU(menu_item));
962 gtk_widget_set_sensitive(menu_item, val);
964 /* be sure this menu item *is* existing */
965 g_assert_not_reached();
973 set_menu_object_data_meat(GtkItemFactory *ifactory, const gchar *path, const gchar *key, gpointer data)
975 GtkWidget *menu = NULL;
977 if ((menu = gtk_item_factory_get_widget(ifactory, path)) != NULL)
978 OBJECT_SET_DATA(menu, key, data);
982 set_menu_object_data (const gchar *path, const gchar *key, gpointer data) {
983 GSList *menu_list = popup_menu_list;
984 gchar *shortpath = strrchr(path, '/');
986 set_menu_object_data_meat(main_menu_factory, path, key, data);
987 while (menu_list != NULL) {
988 set_menu_object_data_meat(menu_list->data, shortpath, key, data);
989 menu_list = g_slist_next(menu_list);
994 /* Recently used capture files submenu:
995 * Submenu containing the recently used capture files.
996 * The capture filenames are always kept with the absolute path, to be independant
997 * of the current path.
998 * They are only stored inside the labels of the submenu (no separate list). */
1000 #define MENU_RECENT_FILES_PATH "/File/Open Recent"
1001 #define MENU_RECENT_FILES_KEY "Recent File Name"
1004 update_menu_recent_capture_file1(GtkWidget *widget, gpointer cnt) {
1005 gchar *widget_cf_name;
1007 widget_cf_name = OBJECT_GET_DATA(widget, MENU_RECENT_FILES_KEY);
1009 /* if this menu item is a file, count it */
1010 if (widget_cf_name) {
1016 /* update the menu */
1018 update_menu_recent_capture_file(GtkWidget *submenu_recent_files) {
1021 gtk_container_foreach(GTK_CONTAINER(submenu_recent_files),
1022 update_menu_recent_capture_file1, &cnt);
1024 /* make parent menu item sensitive only, if we have any valid files in the list */
1025 set_menu_sensitivity(main_menu_factory, MENU_RECENT_FILES_PATH, cnt);
1029 /* remove the capture filename from the "Recent Files" menu */
1031 remove_menu_recent_capture_file(GtkWidget *widget, gpointer unused _U_) {
1032 GtkWidget *submenu_recent_files;
1033 gchar *widget_cf_name;
1036 widget_cf_name = OBJECT_GET_DATA(widget, MENU_RECENT_FILES_KEY);
1037 g_free(widget_cf_name);
1039 /* get the submenu container item */
1040 submenu_recent_files = gtk_item_factory_get_widget(main_menu_factory, MENU_RECENT_FILES_PATH);
1042 /* XXX: is this all we need to do, to free the menu item and its label?
1043 The reference count of widget will go to 0, so it'll be freed;
1044 will that free the label? */
1045 gtk_container_remove(GTK_CONTAINER(submenu_recent_files), widget);
1049 /* callback, if the user pushed the <Clear File List> item */
1051 clear_menu_recent_capture_file_cmd_cb(GtkWidget *w _U_, gpointer unused _U_) {
1052 GtkWidget *submenu_recent_files;
1055 submenu_recent_files = gtk_item_factory_get_widget(main_menu_factory, MENU_RECENT_FILES_PATH);
1057 gtk_container_foreach(GTK_CONTAINER(submenu_recent_files),
1058 remove_menu_recent_capture_file, NULL);
1060 update_menu_recent_capture_file(submenu_recent_files);
1064 /* callback, if the user pushed a recent file submenu item */
1066 menu_open_recent_file_cmd(GtkWidget *w)
1068 GtkWidget *submenu_recent_files;
1069 GtkWidget *menu_item_child;
1073 submenu_recent_files = gtk_item_factory_get_widget(main_menu_factory, MENU_RECENT_FILES_PATH);
1075 /* get capture filename from the menu item label */
1076 menu_item_child = (GTK_BIN(w))->child;
1077 gtk_label_get(GTK_LABEL(menu_item_child), &cf_name);
1079 /* open and read the capture file (this will close an existing file) */
1080 if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
1083 /* the capture file isn't existing any longer, remove menu item */
1084 /* XXX: ask user to remove item, it's maybe only a temporary problem */
1085 remove_menu_recent_capture_file(w, NULL);
1088 update_menu_recent_capture_file(submenu_recent_files);
1091 static void menu_open_recent_file_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
1095 /* save file first */
1096 file_save_as_cmd(after_save_open_recent_file, data);
1100 menu_open_recent_file_cmd(data);
1102 case(ESD_BTN_CANCEL):
1105 g_assert_not_reached();
1110 menu_open_recent_file_cmd_cb(GtkWidget *widget, gpointer data _U_) {
1114 if((cfile.state != FILE_CLOSED) && !cfile.user_saved && prefs.gui_ask_unsaved) {
1115 /* user didn't saved his current file, ask him */
1116 dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO_CANCEL,
1117 PRIMARY_TEXT_START "Save capture file before opening a new one?" PRIMARY_TEXT_END "\n\n"
1118 "If you open a new capture file without saving, your current capture data will be discarded.");
1119 simple_dialog_set_cb(dialog, menu_open_recent_file_answered_cb, widget);
1121 /* unchanged file */
1122 menu_open_recent_file_cmd(widget);
1126 /* add the capture filename (with an absolute path) to the "Recent Files" menu */
1128 add_menu_recent_capture_file_absolute(gchar *cf_name) {
1129 GtkWidget *submenu_recent_files;
1130 GList *menu_item_list;
1132 gchar *widget_cf_name;
1133 gchar *normalized_cf_name;
1134 GtkWidget *menu_item;
1139 normalized_cf_name = g_strdup(cf_name);
1141 /* replace all slashes by backslashes */
1142 g_strdelimit(normalized_cf_name, "/", '\\');
1145 /* get the submenu container item */
1146 submenu_recent_files = gtk_item_factory_get_widget(main_menu_factory, MENU_RECENT_FILES_PATH);
1148 /* convert container to a GList */
1149 menu_item_list = gtk_container_children(GTK_CONTAINER(submenu_recent_files));
1151 /* iterate through list items of menu_item_list,
1152 * removing special items, a maybe duplicate entry and every item above count_max */
1154 for (li = g_list_first(menu_item_list); li; li = li->next, cnt++) {
1155 /* get capture filename */
1156 menu_item = GTK_WIDGET(li->data);
1157 widget_cf_name = OBJECT_GET_DATA(menu_item, MENU_RECENT_FILES_KEY);
1159 /* if this element string is one of our special items (seperator, ...) or
1160 * already in the list or
1161 * this element is above maximum count (too old), remove it */
1162 if (!widget_cf_name ||
1164 /* do a case insensitive compare on win32 */
1165 #if GLIB_MAJOR_VERSION < 2
1166 g_strncasecmp(widget_cf_name, normalized_cf_name, 1000) == 0 ||
1168 g_ascii_strncasecmp(widget_cf_name, normalized_cf_name, 1000) == 0 ||
1171 /* do a case sensitive compare on unix */
1172 strncmp(widget_cf_name, normalized_cf_name, 1000) == 0 ||
1174 cnt >= prefs.gui_recent_files_count_max) {
1175 remove_menu_recent_capture_file(li->data, NULL);
1180 g_list_free(menu_item_list);
1182 /* add new item at latest position */
1183 menu_item = gtk_menu_item_new_with_label(normalized_cf_name);
1184 OBJECT_SET_DATA(menu_item, MENU_RECENT_FILES_KEY, normalized_cf_name);
1185 gtk_menu_prepend (GTK_MENU(submenu_recent_files), menu_item);
1186 SIGNAL_CONNECT_OBJECT(GTK_OBJECT(menu_item), "activate",
1187 menu_open_recent_file_cmd_cb, (GtkObject *) menu_item);
1188 gtk_widget_show (menu_item);
1190 /* add seperator at last position */
1191 menu_item = gtk_menu_item_new();
1192 gtk_menu_append (GTK_MENU(submenu_recent_files), menu_item);
1193 gtk_widget_show (menu_item);
1195 /* add new "clear list" item at last position */
1196 #if GTK_MAJOR_VERSION < 2
1197 menu_item = gtk_menu_item_new_with_label("<Clear File List>");
1199 menu_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_CLEAR, NULL);
1201 gtk_menu_append (GTK_MENU(submenu_recent_files), menu_item);
1202 SIGNAL_CONNECT_OBJECT(GTK_OBJECT(menu_item), "activate",
1203 clear_menu_recent_capture_file_cmd_cb, (GtkObject *) menu_item);
1204 gtk_widget_show (menu_item);
1206 update_menu_recent_capture_file(submenu_recent_files);
1210 /* add the capture filename to the "Recent Files" menu */
1211 /* (will change nothing, if this filename is already in the menu) */
1213 add_menu_recent_capture_file(gchar *cf_name) {
1218 /* if this filename is an absolute path, we can use it directly */
1219 if (g_path_is_absolute(cf_name)) {
1220 add_menu_recent_capture_file_absolute(cf_name);
1224 /* this filename is not an absolute path, prepend the current dir */
1225 curr = g_get_current_dir();
1226 absolute = g_strdup_printf("%s%s%s", curr, G_DIR_SEPARATOR_S, cf_name);
1227 add_menu_recent_capture_file_absolute(absolute);
1233 /* write all capture filenames of the menu to the user's recent file */
1235 menu_recent_file_write_all(FILE *rf) {
1236 GtkWidget *submenu_recent_files;
1242 submenu_recent_files = gtk_item_factory_get_widget(main_menu_factory, MENU_RECENT_FILES_PATH);
1244 /* we have to iterate backwards through the children's list,
1245 * so we get the latest item last in the file.
1246 * (don't use gtk_container_foreach() here, it will return the wrong iteration order) */
1247 children = gtk_container_children(GTK_CONTAINER(submenu_recent_files));
1248 child = g_list_last(children);
1249 while(child != NULL) {
1250 /* get capture filename from the menu item label */
1251 cf_name = OBJECT_GET_DATA(child->data, MENU_RECENT_FILES_KEY);
1253 fprintf (rf, RECENT_KEY_CAPTURE_FILE ": %s\n", cf_name);
1256 child = g_list_previous(child);
1259 g_list_free(children);
1264 main_toolbar_show_cb(GtkWidget *w _U_, gpointer d _U_)
1267 /* save current setting in recent */
1268 recent.main_toolbar_show = GTK_CHECK_MENU_ITEM(w)->active;
1270 main_widgets_show_or_hide();
1275 filter_toolbar_show_cb(GtkWidget *w _U_, gpointer d _U_)
1278 /* save current setting in recent */
1279 recent.filter_toolbar_show = GTK_CHECK_MENU_ITEM(w)->active;
1281 main_widgets_show_or_hide();
1286 packet_list_show_cb(GtkWidget *w _U_, gpointer d _U_)
1289 /* save current setting in recent */
1290 recent.packet_list_show = GTK_CHECK_MENU_ITEM(w)->active;
1292 main_widgets_show_or_hide();
1297 tree_view_show_cb(GtkWidget *w _U_, gpointer d _U_)
1300 /* save current setting in recent */
1301 recent.tree_view_show = GTK_CHECK_MENU_ITEM(w)->active;
1303 main_widgets_show_or_hide();
1308 byte_view_show_cb(GtkWidget *w _U_, gpointer d _U_)
1311 /* save current setting in recent */
1312 recent.byte_view_show = GTK_CHECK_MENU_ITEM(w)->active;
1314 main_widgets_show_or_hide();
1319 statusbar_show_cb(GtkWidget *w _U_, gpointer d _U_)
1322 /* save current setting in recent */
1323 recent.statusbar_show = GTK_CHECK_MENU_ITEM(w)->active;
1325 main_widgets_show_or_hide();
1330 timestamp_absolute_cb(GtkWidget *w _U_, gpointer d _U_)
1332 if (recent.gui_time_format != TS_ABSOLUTE) {
1333 timestamp_set_type(TS_ABSOLUTE);
1334 recent.gui_time_format = TS_ABSOLUTE;
1335 cf_change_time_formats(&cfile);
1340 timestamp_absolute_date_cb(GtkWidget *w _U_, gpointer d _U_)
1342 if (recent.gui_time_format != TS_ABSOLUTE_WITH_DATE) {
1343 timestamp_set_type(TS_ABSOLUTE_WITH_DATE);
1344 recent.gui_time_format = TS_ABSOLUTE_WITH_DATE;
1345 cf_change_time_formats(&cfile);
1350 timestamp_relative_cb(GtkWidget *w _U_, gpointer d _U_)
1352 if (recent.gui_time_format != TS_RELATIVE) {
1353 timestamp_set_type(TS_RELATIVE);
1354 recent.gui_time_format = TS_RELATIVE;
1355 cf_change_time_formats(&cfile);
1360 timestamp_delta_cb(GtkWidget *w _U_, gpointer d _U_)
1362 if (recent.gui_time_format != TS_DELTA) {
1363 timestamp_set_type(TS_DELTA);
1364 recent.gui_time_format = TS_DELTA;
1365 cf_change_time_formats(&cfile);
1370 timestamp_auto_cb(GtkWidget *w _U_, gpointer d _U_)
1372 if (recent.gui_time_precision != TS_PREC_AUTO) {
1373 /* the actual precision will be set in cf_change_time_formats() below */
1374 timestamp_set_precision(TS_PREC_AUTO_SEC);
1375 recent.gui_time_precision = TS_PREC_AUTO;
1376 cf_change_time_formats(&cfile);
1381 timestamp_sec_cb(GtkWidget *w _U_, gpointer d _U_)
1383 if (recent.gui_time_precision != TS_PREC_FIXED_SEC) {
1384 timestamp_set_precision(TS_PREC_FIXED_SEC);
1385 recent.gui_time_precision = TS_PREC_FIXED_SEC;
1386 cf_change_time_formats(&cfile);
1391 timestamp_dsec_cb(GtkWidget *w _U_, gpointer d _U_)
1393 if (recent.gui_time_precision != TS_PREC_FIXED_DSEC) {
1394 timestamp_set_precision(TS_PREC_FIXED_DSEC);
1395 recent.gui_time_precision = TS_PREC_FIXED_DSEC;
1396 cf_change_time_formats(&cfile);
1401 timestamp_csec_cb(GtkWidget *w _U_, gpointer d _U_)
1403 if (recent.gui_time_precision != TS_PREC_FIXED_CSEC) {
1404 timestamp_set_precision(TS_PREC_FIXED_CSEC);
1405 recent.gui_time_precision = TS_PREC_FIXED_CSEC;
1406 cf_change_time_formats(&cfile);
1411 timestamp_msec_cb(GtkWidget *w _U_, gpointer d _U_)
1413 if (recent.gui_time_precision != TS_PREC_FIXED_MSEC) {
1414 timestamp_set_precision(TS_PREC_FIXED_MSEC);
1415 recent.gui_time_precision = TS_PREC_FIXED_MSEC;
1416 cf_change_time_formats(&cfile);
1421 timestamp_usec_cb(GtkWidget *w _U_, gpointer d _U_)
1423 if (recent.gui_time_precision != TS_PREC_FIXED_USEC) {
1424 timestamp_set_precision(TS_PREC_FIXED_USEC);
1425 recent.gui_time_precision = TS_PREC_FIXED_USEC;
1426 cf_change_time_formats(&cfile);
1431 timestamp_nsec_cb(GtkWidget *w _U_, gpointer d _U_)
1433 if (recent.gui_time_precision != TS_PREC_FIXED_NSEC) {
1434 timestamp_set_precision(TS_PREC_FIXED_NSEC);
1435 recent.gui_time_precision = TS_PREC_FIXED_NSEC;
1436 cf_change_time_formats(&cfile);
1442 menu_name_resolution_changed(void)
1444 GtkWidget *menu = NULL;
1446 menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Name Resolution/Enable for MAC Layer");
1447 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), g_resolv_flags & RESOLV_MAC);
1449 menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Name Resolution/Enable for Network Layer");
1450 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), g_resolv_flags & RESOLV_NETWORK);
1452 menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Name Resolution/Enable for Transport Layer");
1453 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), g_resolv_flags & RESOLV_TRANSPORT);
1457 name_resolution_mac_cb(GtkWidget *w _U_, gpointer d _U_)
1459 if (GTK_CHECK_MENU_ITEM(w)->active) {
1460 g_resolv_flags |= RESOLV_MAC;
1462 g_resolv_flags &= ~RESOLV_MAC;
1467 name_resolution_network_cb(GtkWidget *w _U_, gpointer d _U_)
1469 if (GTK_CHECK_MENU_ITEM(w)->active) {
1470 g_resolv_flags |= RESOLV_NETWORK;
1472 g_resolv_flags &= ~RESOLV_NETWORK;
1477 name_resolution_transport_cb(GtkWidget *w _U_, gpointer d _U_)
1479 if (GTK_CHECK_MENU_ITEM(w)->active) {
1480 g_resolv_flags |= RESOLV_TRANSPORT;
1482 g_resolv_flags &= ~RESOLV_TRANSPORT;
1488 menu_auto_scroll_live_changed(gboolean auto_scroll_live_in) {
1492 /* tell menu about it */
1493 menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Auto Scroll in Live Capture");
1494 if( ((gboolean) GTK_CHECK_MENU_ITEM(menu)->active) != auto_scroll_live_in) {
1495 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), auto_scroll_live_in);
1498 /* tell toolbar about it */
1499 toolbar_auto_scroll_live_changed(auto_scroll_live_in);
1501 /* change auto scroll */
1502 if(auto_scroll_live_in != auto_scroll_live) {
1503 auto_scroll_live = auto_scroll_live_in;
1508 auto_scroll_live_cb(GtkWidget *w _U_, gpointer d _U_)
1510 menu_auto_scroll_live_changed(GTK_CHECK_MENU_ITEM(w)->active);
1516 menu_colorize_changed(gboolean packet_list_colorize) {
1520 /* tell menu about it */
1521 menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Colorize Packet List");
1522 if( ((gboolean) GTK_CHECK_MENU_ITEM(menu)->active) != packet_list_colorize) {
1523 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), packet_list_colorize);
1526 /* tell toolbar about it */
1527 toolbar_colorize_changed(packet_list_colorize);
1529 /* change colorization */
1530 if(packet_list_colorize != recent.packet_list_colorize) {
1531 recent.packet_list_colorize = packet_list_colorize;
1532 color_filters_enable(packet_list_colorize);
1533 cf_colorize_packets(&cfile);
1538 colorize_cb(GtkWidget *w, gpointer d _U_)
1540 menu_colorize_changed(GTK_CHECK_MENU_ITEM(w)->active);
1544 /* the recent file read has finished, update the menu corresponding */
1546 menu_recent_read_finished(void) {
1547 GtkWidget *menu = NULL;
1549 menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Main Toolbar");
1550 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), recent.main_toolbar_show);
1552 menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Filter Toolbar");
1553 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), recent.filter_toolbar_show);
1555 menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Statusbar");
1556 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), recent.statusbar_show);
1558 menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Packet List");
1559 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), recent.packet_list_show);
1561 menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Packet Details");
1562 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), recent.tree_view_show);
1564 menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Packet Bytes");
1565 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), recent.byte_view_show);
1567 menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Colorize Packet List");
1568 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), recent.packet_list_colorize);
1570 menu_name_resolution_changed();
1573 menu = gtk_item_factory_get_widget(main_menu_factory, "/View/Auto Scroll in Live Capture");
1574 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), auto_scroll_live);
1577 main_widgets_rearrange();
1579 /* don't change the time format, if we had a command line value */
1580 if (timestamp_get_type() != TS_NOT_SET) {
1581 recent.gui_time_format = timestamp_get_type();
1584 switch(recent.gui_time_format) {
1585 case(TS_ABSOLUTE_WITH_DATE):
1586 menu = gtk_item_factory_get_widget(main_menu_factory,
1587 "/View/Time Display Format/Date and Time of Day: 1970-01-01 01:02:03.123456");
1588 /* set_active will not trigger the callback when activating an active item! */
1589 recent.gui_time_format = -1;
1590 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), FALSE);
1591 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE);
1594 menu = gtk_item_factory_get_widget(main_menu_factory,
1595 "/View/Time Display Format/Time of Day: 01:02:03.123456");
1596 /* set_active will not trigger the callback when activating an active item! */
1597 recent.gui_time_format = -1;
1598 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE);
1601 menu = gtk_item_factory_get_widget(main_menu_factory,
1602 "/View/Time Display Format/Seconds Since Beginning of Capture: 123.123456");
1603 recent.gui_time_format = -1;
1604 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE);
1607 menu = gtk_item_factory_get_widget(main_menu_factory,
1608 "/View/Time Display Format/Seconds Since Previous Packet: 1.123456");
1609 recent.gui_time_format = -1;
1610 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE);
1613 g_assert_not_reached();
1616 switch(recent.gui_time_precision) {
1618 menu = gtk_item_factory_get_widget(main_menu_factory,
1619 "/View/Time Display Format/Automatic (File Format Precision)");
1620 /* set_active will not trigger the callback when activating an active item! */
1621 recent.gui_time_precision = -1;
1622 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), FALSE);
1623 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE);
1625 case(TS_PREC_FIXED_SEC):
1626 menu = gtk_item_factory_get_widget(main_menu_factory,
1627 "/View/Time Display Format/Seconds: 0");
1628 recent.gui_time_precision = -1;
1629 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE);
1631 case(TS_PREC_FIXED_DSEC):
1632 menu = gtk_item_factory_get_widget(main_menu_factory,
1633 "/View/Time Display Format/Deciseconds: 0.1");
1634 recent.gui_time_precision = -1;
1635 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE);
1637 case(TS_PREC_FIXED_CSEC):
1638 menu = gtk_item_factory_get_widget(main_menu_factory,
1639 "/View/Time Display Format/Centiseconds: 0.12");
1640 recent.gui_time_precision = -1;
1641 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE);
1643 case(TS_PREC_FIXED_MSEC):
1644 menu = gtk_item_factory_get_widget(main_menu_factory,
1645 "/View/Time Display Format/Milliseconds: 0.123");
1646 recent.gui_time_precision = -1;
1647 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE);
1649 case(TS_PREC_FIXED_USEC):
1650 menu = gtk_item_factory_get_widget(main_menu_factory,
1651 "/View/Time Display Format/Microseconds: 0.123456");
1652 recent.gui_time_precision = -1;
1653 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE);
1655 case(TS_PREC_FIXED_NSEC):
1656 menu = gtk_item_factory_get_widget(main_menu_factory,
1657 "/View/Time Display Format/Nanoseconds: 0.123456789");
1658 recent.gui_time_precision = -1;
1659 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), TRUE);
1662 g_assert_not_reached();
1665 menu_colorize_changed(recent.packet_list_colorize);
1670 popup_menu_handler(GtkWidget *widget, GdkEvent *event, gpointer data)
1672 GtkWidget *menu = (GtkWidget *)data;
1673 GdkEventButton *event_button = NULL;
1676 if(widget == NULL || event == NULL || data == NULL) {
1681 * If we ever want to make the menu differ based on what row
1682 * and/or column we're above, we'd use "eth_clist_get_selection_info()"
1683 * to find the row and column number for the coordinates; a CTree is,
1684 * I guess, like a CList with one column(?) and the expander widget
1687 /* Check if we are on packet_list object */
1688 if (widget == OBJECT_GET_DATA(popup_menu_object, E_MPACKET_LIST_KEY)) {
1689 if (packet_list_get_event_row_column(widget, (GdkEventButton *)event,
1691 OBJECT_SET_DATA(popup_menu_object, E_MPACKET_LIST_ROW_KEY,
1692 GINT_TO_POINTER(row));
1693 OBJECT_SET_DATA(popup_menu_object, E_MPACKET_LIST_COL_KEY,
1694 GINT_TO_POINTER(column));
1695 packet_list_set_selected_row(row);
1699 /* Check if we are on tree_view object */
1700 if (widget == tree_view) {
1701 tree_view_select(widget, (GdkEventButton *) event);
1704 /* Check if we are on byte_view object */
1705 if(widget == get_notebook_bv_ptr(byte_nb_ptr)) {
1706 byte_view_select(widget, (GdkEventButton *) event);
1709 /* context menu handler (but the byte view notebook pages have their own handler) */
1710 if(event->type == GDK_BUTTON_PRESS && widget != byte_nb_ptr) {
1711 event_button = (GdkEventButton *) event;
1713 /* To qoute the "Gdk Event Structures" doc:
1714 * "Normally button 1 is the left mouse button, 2 is the middle button, and 3 is the right button" */
1715 if(event_button->button == 3) {
1716 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
1717 event_button->button,
1718 event_button->time);
1719 SIGNAL_EMIT_STOP_BY_NAME(widget, "button_press_event");
1723 #if GTK_MAJOR_VERSION >= 2
1724 /* GDK_2BUTTON_PRESS is a doubleclick -> expand/collapse tree row */
1725 /* GTK version 1 seems to be doing this automatically */
1726 if (widget == tree_view && event->type == GDK_2BUTTON_PRESS) {
1729 if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget),
1730 (gint) (((GdkEventButton *)event)->x),
1731 (gint) (((GdkEventButton *)event)->y),
1732 &path, NULL, NULL, NULL))
1734 if (gtk_tree_view_row_expanded(GTK_TREE_VIEW(widget), path))
1735 gtk_tree_view_collapse_row(GTK_TREE_VIEW(widget), path);
1737 gtk_tree_view_expand_row(GTK_TREE_VIEW(widget), path,
1739 gtk_tree_path_free(path);
1746 /* Enable or disable menu items based on whether you have a capture file
1747 you've finished reading. */
1749 set_menus_for_capture_file(gboolean have_capture_file)
1751 set_menu_sensitivity(main_menu_factory, "/File/Open...", have_capture_file);
1752 set_menu_sensitivity(main_menu_factory, "/File/Open Recent", have_capture_file);
1753 set_menu_sensitivity(main_menu_factory, "/File/Merge...", have_capture_file);
1754 set_menu_sensitivity(main_menu_factory, "/File/Close", have_capture_file);
1755 set_menu_sensitivity(main_menu_factory, "/File/Save As...",
1757 set_menu_sensitivity(main_menu_factory, "/File/Export", have_capture_file);
1758 set_menu_sensitivity(main_menu_factory, "/View/Reload", have_capture_file);
1759 set_toolbar_for_capture_file(have_capture_file);
1760 packets_bar_update();
1763 /* Enable or disable menu items based on whether you have an unsaved
1764 capture file you've finished reading. */
1766 set_menus_for_unsaved_capture_file(gboolean have_unsaved_capture_file)
1768 set_menu_sensitivity(main_menu_factory, "/File/Save",
1769 have_unsaved_capture_file);
1770 set_toolbar_for_unsaved_capture_file(have_unsaved_capture_file);
1773 /* Enable or disable menu items based on whether there's a capture in
1776 set_menus_for_capture_in_progress(gboolean capture_in_progress)
1778 set_menu_sensitivity(main_menu_factory, "/File/Open...",
1779 !capture_in_progress);
1780 set_menu_sensitivity(main_menu_factory, "/File/Open Recent",
1781 !capture_in_progress);
1783 set_menu_sensitivity(main_menu_factory, "/Capture/Options...",
1784 !capture_in_progress);
1785 set_menu_sensitivity(main_menu_factory, "/Capture/Start",
1786 !capture_in_progress);
1787 set_menu_sensitivity(main_menu_factory, "/Capture/Stop",
1788 capture_in_progress);
1789 set_menu_sensitivity(main_menu_factory, "/Capture/Restart",
1790 capture_in_progress);
1791 set_toolbar_for_capture_in_progress(capture_in_progress);
1793 set_capture_if_dialog_for_capture_in_progress(capture_in_progress);
1794 #endif /* HAVE_LIBPCAP */
1797 /* Enable or disable menu items based on whether you have some captured
1800 walk_menu_tree_for_captured_packets(GList *node,
1801 gboolean have_captured_packets)
1803 gboolean is_enabled;
1805 menu_item_t *node_data = node->data;
1808 * Is this a leaf node or an interior node?
1810 if (node_data->children == NULL) {
1814 * If it has no "selected_packet_enabled()" or
1815 * "selected_tree_row_enabled()" routines, we enable
1816 * it. This allows tap windows to be popped up even
1817 * if you have no capture file; this is done to let
1818 * the user pop up multiple tap windows before reading
1819 * in a capture file, so that they can be processed in
1820 * parallel while the capture file is being read rather
1821 * than one at at time as you pop up the windows, and to
1822 * let the user pop up tap windows before starting an
1823 * "Update list of packets in real time" capture, so that
1824 * the statistics can be displayed while the capture is
1827 * If it has either of those routines, we disable it for
1828 * now - as long as, when a capture is first available,
1829 * we don't get called after a packet or tree row is
1830 * selected, that's OK.
1831 * XXX - that should be done better.
1833 if (node_data->selected_packet_enabled == NULL &&
1834 node_data->selected_tree_row_enabled == NULL)
1835 node_data->enabled = TRUE;
1837 node_data->enabled = FALSE;
1840 * It's an interior node; call
1841 * "walk_menu_tree_for_captured_packets()" on all its
1842 * children and, if any of them are enabled, enable
1843 * this node, otherwise disable it.
1845 * XXX - should we just leave all interior nodes enabled?
1846 * Which is a better UI choice?
1849 for (child = node_data->children; child != NULL; child =
1851 if (walk_menu_tree_for_captured_packets(child,
1852 have_captured_packets))
1855 node_data->enabled = is_enabled;
1859 * The root node doesn't correspond to a menu tree item; it
1860 * has a null name pointer.
1862 if (node_data->name != NULL) {
1863 set_menu_sensitivity(main_menu_factory, node_data->name,
1864 node_data->enabled);
1866 return node_data->enabled;
1870 set_menus_for_captured_packets(gboolean have_captured_packets)
1872 set_menu_sensitivity(main_menu_factory, "/File/Print...",
1873 have_captured_packets);
1874 set_menu_sensitivity(packet_list_menu_factory, "/Print...",
1875 have_captured_packets);
1876 set_menu_sensitivity(main_menu_factory, "/Edit/Find Packet...",
1877 have_captured_packets);
1878 set_menu_sensitivity(main_menu_factory, "/Edit/Find Next",
1879 have_captured_packets);
1880 set_menu_sensitivity(main_menu_factory, "/Edit/Find Previous",
1881 have_captured_packets);
1882 set_menu_sensitivity(main_menu_factory, "/View/Zoom In",
1883 have_captured_packets);
1884 set_menu_sensitivity(main_menu_factory, "/View/Zoom Out",
1885 have_captured_packets);
1886 set_menu_sensitivity(main_menu_factory, "/View/Normal Size",
1887 have_captured_packets);
1888 set_menu_sensitivity(main_menu_factory, "/Go/Go to Packet...",
1889 have_captured_packets);
1890 set_menu_sensitivity(main_menu_factory, "/Go/First Packet",
1891 have_captured_packets);
1892 set_menu_sensitivity(main_menu_factory, "/Go/Last Packet",
1893 have_captured_packets);
1894 set_menu_sensitivity(main_menu_factory, "/Statistics/Summary",
1895 have_captured_packets);
1896 set_menu_sensitivity(main_menu_factory, "/Statistics/Protocol Hierarchy",
1897 have_captured_packets);
1899 walk_menu_tree_for_captured_packets(tap_menu_tree_root,
1900 have_captured_packets);
1901 set_toolbar_for_captured_packets(have_captured_packets);
1902 packets_bar_update();
1905 /* Enable or disable menu items based on whether a packet is selected and,
1906 if so, on the properties of the packet. */
1908 walk_menu_tree_for_selected_packet(GList *node, frame_data *fd,
1909 epan_dissect_t *edt)
1911 gboolean is_enabled;
1913 menu_item_t *node_data = node->data;
1916 * Is this a leaf node or an interior node?
1918 if (node_data->children == NULL) {
1922 * If it has no "selected_packet_enabled()" routine,
1923 * leave its enabled/disabled status alone - it
1924 * doesn't depend on whether we have a packet selected
1925 * or not or on the selected packet.
1927 * If it has a "selected_packet_enabled()" routine,
1928 * call it and set the item's enabled/disabled status
1929 * based on its return value.
1931 if (node_data->selected_packet_enabled != NULL)
1932 node_data->enabled = node_data->selected_packet_enabled(fd, edt);
1935 * It's an interior node; call
1936 * "walk_menu_tree_for_selected_packet()" on all its
1937 * children and, if any of them are enabled, enable
1938 * this node, otherwise disable it.
1940 * XXX - should we just leave all interior nodes enabled?
1941 * Which is a better UI choice?
1944 for (child = node_data->children; child != NULL; child =
1946 if (walk_menu_tree_for_selected_packet(child, fd, edt))
1949 node_data->enabled = is_enabled;
1953 * The root node doesn't correspond to a menu tree item; it
1954 * has a null name pointer.
1956 if (node_data->name != NULL) {
1957 set_menu_sensitivity(main_menu_factory, node_data->name,
1958 node_data->enabled);
1960 return node_data->enabled;
1964 packet_is_ssl(epan_dissect_t* edt)
1968 if (!edt || !edt->tree)
1970 ssl_id = proto_get_id_by_filter_name("ssl");
1973 array = proto_find_finfo(edt->tree, ssl_id);
1974 is_ssl = array->len > 0;
1975 g_ptr_array_free(array, FALSE);
1980 set_menus_for_selected_packet(capture_file *cf)
1982 int is_ssl = packet_is_ssl(cf->edt);
1983 set_menu_sensitivity(main_menu_factory, "/Edit/Mark Packet (toggle)",
1984 cf->current_frame != NULL);
1985 set_menu_sensitivity(packet_list_menu_factory, "/Mark Packet (toggle)",
1986 cf->current_frame != NULL);
1987 set_menu_sensitivity(main_menu_factory, "/Edit/Time Reference",
1988 cf->current_frame != NULL);
1989 set_menu_sensitivity(packet_list_menu_factory, "/Time Reference",
1990 cf->current_frame != NULL);
1991 set_menu_sensitivity(main_menu_factory, "/Edit/Mark All Packets",
1992 cf->current_frame != NULL);
1993 set_menu_sensitivity(main_menu_factory, "/Edit/Unmark All Packets",
1994 cf->current_frame != NULL);
1995 set_menu_sensitivity(main_menu_factory, "/View/Resize All Columns",
1996 cf->current_frame != NULL);
1997 set_menu_sensitivity(main_menu_factory, "/View/Collapse All",
1998 cf->current_frame != NULL);
1999 set_menu_sensitivity(tree_view_menu_factory, "/Collapse All",
2000 cf->current_frame != NULL);
2001 set_menu_sensitivity(main_menu_factory, "/View/Expand All",
2002 cf->current_frame != NULL);
2003 set_menu_sensitivity(tree_view_menu_factory, "/Expand All",
2004 cf->current_frame != NULL);
2005 set_menu_sensitivity(main_menu_factory, "/View/Show Packet in New Window",
2006 cf->current_frame != NULL);
2007 set_menu_sensitivity(packet_list_menu_factory, "/Show Packet in New Window",
2008 cf->current_frame != NULL);
2009 set_menu_sensitivity(main_menu_factory, "/Analyze/Follow TCP Stream",
2010 cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_TCP) : FALSE);
2011 set_menu_sensitivity(packet_list_menu_factory, "/Follow TCP Stream",
2012 cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_TCP) : FALSE);
2013 set_menu_sensitivity(tree_view_menu_factory, "/Follow TCP Stream",
2014 cf->current_frame != NULL ? (cf->edt->pi.ipproto == IP_PROTO_TCP) : FALSE);
2015 set_menu_sensitivity(main_menu_factory, "/Analyze/Follow SSL Stream",
2016 cf->current_frame != NULL ? is_ssl : FALSE);
2017 set_menu_sensitivity(packet_list_menu_factory, "/Follow SSL Stream",
2018 cf->current_frame != NULL ? is_ssl : FALSE);
2019 set_menu_sensitivity(tree_view_menu_factory, "/Follow SSL Stream",
2020 cf->current_frame != NULL ? is_ssl : FALSE);
2021 set_menu_sensitivity(main_menu_factory, "/Analyze/Decode As...",
2022 cf->current_frame != NULL && decode_as_ok());
2023 set_menu_sensitivity(packet_list_menu_factory, "/Decode As...",
2024 cf->current_frame != NULL && decode_as_ok());
2025 set_menu_sensitivity(tree_view_menu_factory, "/Decode As...",
2026 cf->current_frame != NULL && decode_as_ok());
2027 set_menu_sensitivity(main_menu_factory, "/View/Name Resolution/Resolve Name",
2028 cf->current_frame != NULL && (g_resolv_flags & RESOLV_ALL_ADDRS) != RESOLV_ALL_ADDRS);
2029 set_menu_sensitivity(tree_view_menu_factory, "/Resolve Name",
2030 cf->current_frame != NULL && (g_resolv_flags & RESOLV_ALL_ADDRS) != RESOLV_ALL_ADDRS);
2031 set_menu_sensitivity(packet_list_menu_factory, "/Apply as Filter",
2032 cf->current_frame != NULL);
2033 set_menu_sensitivity(packet_list_menu_factory, "/Prepare a Filter",
2034 cf->current_frame != NULL);
2036 walk_menu_tree_for_selected_packet(tap_menu_tree_root, cf->current_frame,
2038 packets_bar_update();
2041 /* Enable or disable menu items based on whether a tree row is selected
2042 and, if so, on the properties of the tree row. */
2044 walk_menu_tree_for_selected_tree_row(GList *node, field_info *fi)
2046 gboolean is_enabled;
2048 menu_item_t *node_data = node->data;
2051 * Is this a leaf node or an interior node?
2053 if (node_data->children == NULL) {
2057 * If it has no "selected_tree_row_enabled()" routine,
2058 * leave its enabled/disabled status alone - it
2059 * doesn't depend on whether we have a tree row selected
2060 * or not or on the selected tree row.
2062 * If it has a "selected_tree_row_enabled()" routine,
2063 * call it and set the item's enabled/disabled status
2064 * based on its return value.
2066 if (node_data->selected_tree_row_enabled != NULL)
2067 node_data->enabled = node_data->selected_tree_row_enabled(fi);
2070 * It's an interior node; call
2071 * "walk_menu_tree_for_selected_tree_row()" on all its
2072 * children and, if any of them are enabled, enable
2073 * this node, otherwise disable it.
2075 * XXX - should we just leave all interior nodes enabled?
2076 * Which is a better UI choice?
2079 for (child = node_data->children; child != NULL; child =
2081 if (walk_menu_tree_for_selected_tree_row(child, fi))
2084 node_data->enabled = is_enabled;
2088 * The root node doesn't correspond to a menu tree item; it
2089 * has a null name pointer.
2091 if (node_data->name != NULL) {
2092 set_menu_sensitivity(main_menu_factory, node_data->name,
2093 node_data->enabled);
2095 return node_data->enabled;
2099 set_menus_for_selected_tree_row(capture_file *cf)
2101 gboolean properties;
2104 set_menu_sensitivity(main_menu_factory, "/File/Export/Selected Packet Bytes...",
2105 cf->finfo_selected != NULL);
2106 set_menu_sensitivity(hexdump_menu_factory, "/Copy",
2107 cf->finfo_selected != NULL);
2108 set_menu_sensitivity(hexdump_menu_factory, "/Export Selected Packet Bytes...",
2109 cf->finfo_selected != NULL);
2111 if (cf->finfo_selected != NULL) {
2112 header_field_info *hfinfo = cf->finfo_selected->hfinfo;
2113 if (hfinfo->parent == -1) {
2114 properties = prefs_is_registered_protocol(hfinfo->abbrev);
2116 properties = prefs_is_registered_protocol(proto_registrar_get_abbrev(hfinfo->parent));
2118 set_menu_sensitivity(main_menu_factory,
2119 "/Go/Go to Corresponding Packet", hfinfo->type == FT_FRAMENUM);
2120 set_menu_sensitivity(tree_view_menu_factory,
2121 "/Go to Corresponding Packet", hfinfo->type == FT_FRAMENUM);
2122 set_menu_sensitivity(main_menu_factory, "/Analyze/Apply as Filter",
2123 proto_can_match_selected(cf->finfo_selected, cf->edt));
2124 set_menu_sensitivity(tree_view_menu_factory, "/Apply as Filter",
2125 proto_can_match_selected(cf->finfo_selected, cf->edt));
2126 set_menu_sensitivity(main_menu_factory, "/Analyze/Prepare a Filter",
2127 proto_can_match_selected(cf->finfo_selected, cf->edt));
2128 set_menu_sensitivity(tree_view_menu_factory, "/Prepare a Filter",
2129 proto_can_match_selected(cf->finfo_selected, cf->edt));
2130 set_menu_sensitivity(tree_view_menu_factory, "/Protocol Preferences...",
2132 set_menu_sensitivity(main_menu_factory, "/View/Expand Subtrees", cf->finfo_selected->tree_type != -1);
2133 set_menu_sensitivity(tree_view_menu_factory, "/Expand Subtrees", cf->finfo_selected->tree_type != -1);
2134 set_menu_sensitivity(tree_view_menu_factory, "/Wiki Protocol Page",
2136 set_menu_sensitivity(tree_view_menu_factory, "/Filter Field Reference",
2139 set_menu_sensitivity(main_menu_factory,
2140 "/Go/Go to Corresponding Packet", FALSE);
2141 set_menu_sensitivity(tree_view_menu_factory,
2142 "/Go to Corresponding Packet", FALSE);
2143 set_menu_sensitivity(main_menu_factory, "/Analyze/Apply as Filter", FALSE);
2144 set_menu_sensitivity(tree_view_menu_factory, "/Apply as Filter", FALSE);
2145 set_menu_sensitivity(main_menu_factory, "/Analyze/Prepare a Filter", FALSE);
2146 set_menu_sensitivity(tree_view_menu_factory, "/Prepare a Filter", FALSE);
2147 set_menu_sensitivity(tree_view_menu_factory, "/Protocol Preferences...",
2149 set_menu_sensitivity(main_menu_factory, "/View/Expand Subtrees", FALSE);
2150 set_menu_sensitivity(tree_view_menu_factory, "/Expand Subtrees", FALSE);
2151 set_menu_sensitivity(tree_view_menu_factory, "/Wiki Protocol Page",
2153 set_menu_sensitivity(tree_view_menu_factory, "/Filter Field Reference",
2157 walk_menu_tree_for_selected_tree_row(tap_menu_tree_root, cf->finfo_selected);
2160 void set_menus_for_packet_history(gboolean back_history, gboolean forward_history) {
2162 set_menu_sensitivity(main_menu_factory, "/Go/Back", back_history);
2163 set_menu_sensitivity(main_menu_factory, "/Go/Forward", forward_history);
2165 set_toolbar_for_packet_history(back_history, forward_history);
2169 void set_menus_for_file_set(gboolean file_set, gboolean previous_file, gboolean next_file) {
2171 set_menu_sensitivity(main_menu_factory, "/File/File Set/List Files", file_set);
2172 set_menu_sensitivity(main_menu_factory, "/File/File Set/Previous File", previous_file);
2173 set_menu_sensitivity(main_menu_factory, "/File/File Set/Next File", next_file);