3 * Copyright 2003, Ulf Lamping <ulf.lamping@web.de>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 * This file implements the "main" toolbar for Wireshark.
36 #include <epan/prefs.h>
37 #include <epan/dfilter/dfilter.h>
39 #include "../color_filters.h"
42 #include "ui/gtk/capture_dlg.h"
43 #include "ui/gtk/capture_if_dlg.h"
44 #endif /* HAVE_LIBPCAP */
45 #include "ui/gtk/filter_dlg.h"
46 #include "ui/gtk/capture_file_dlg.h"
47 #include "ui/gtk/find_dlg.h"
48 #include "ui/gtk/goto_dlg.h"
49 #include "ui/gtk/color_dlg.h"
50 #include "ui/gtk/prefs_dlg.h"
51 #include "ui/gtk/main.h"
52 #include "ui/gtk/menus.h"
53 #include "ui/gtk/main_toolbar.h"
54 #include "ui/gtk/help_dlg.h"
55 #include "ui/gtk/gtkglobals.h"
56 #include "ui/gtk/stock_icons.h"
57 #include "ui/gtk/keys.h"
58 #include "ui/gtk/recent.h"
59 #include "ui/gtk/packet_history.h"
60 #include "ui/gtk/new_packet_list.h"
62 #include "ui/gtk/old-gtk-compat.h"
64 static gboolean toolbar_init = FALSE;
67 static GtkToolItem *capture_options_button, *new_button, *stop_button, *clear_button, *if_button;
68 static GtkToolItem *capture_filter_button, *autoscroll_button;
69 #endif /* HAVE_LIBPCAP */
70 static GtkToolItem *open_button, *save_button, *close_button, *reload_button;
71 static GtkToolItem *print_button, *find_button, *history_forward_button, *history_back_button;
72 static GtkToolItem *go_to_button, *go_to_top_button, *go_to_bottom_button;
73 static GtkToolItem *display_filter_button;
74 static GtkToolItem *zoom_in_button, *zoom_out_button, *zoom_100_button, *colorize_button;
75 static GtkToolItem *resize_columns_button;
76 static GtkToolItem *color_display_button, *prefs_button, *help_button;
78 #define SAVE_BUTTON_TOOLTIP_TEXT "Save this capture file..."
79 #define SAVE_AS_BUTTON_TOOLTIP_TEXT "Save this capture file as..."
86 toolbar_redraw_all(void)
91 main_tb = g_object_get_data(G_OBJECT(top_level), E_TB_MAIN_KEY);
93 gtk_toolbar_set_style(GTK_TOOLBAR(main_tb),
94 prefs.gui_toolbar_main_style);
96 filter_tb = g_object_get_data(G_OBJECT(top_level), E_TB_FILTER_KEY);
98 /* In case the filter toolbar hasn't been built */
100 gtk_toolbar_set_style(GTK_TOOLBAR(filter_tb),
101 prefs.gui_toolbar_filter_style);
104 /* Enable or disable toolbar items based on whether you have a capture file
105 you've finished reading. */
106 void set_toolbar_for_capture_file(gboolean have_capture_file) {
108 gtk_widget_set_sensitive(GTK_WIDGET(save_button), have_capture_file);
109 gtk_widget_set_sensitive(GTK_WIDGET(close_button), have_capture_file);
110 gtk_widget_set_sensitive(GTK_WIDGET(reload_button), have_capture_file);
114 /* Enable or disable menu items based on whether you have an unsaved
115 capture file you've finished reading. */
116 void set_toolbar_for_unsaved_capture_file(gboolean have_unsaved_capture_file) {
119 if(have_unsaved_capture_file) {
120 gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(save_button),
122 gtk_widget_set_tooltip_text(GTK_WIDGET(save_button),SAVE_BUTTON_TOOLTIP_TEXT);
123 g_object_set_data(G_OBJECT(save_button), "save", GINT_TO_POINTER(1));
125 gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(save_button),
127 gtk_widget_set_tooltip_text(GTK_WIDGET(save_button), SAVE_AS_BUTTON_TOOLTIP_TEXT);
128 g_object_set_data(G_OBJECT(save_button), "save", GINT_TO_POINTER(0));
130 /*gtk_widget_set_sensitive((GTK_WIDGET(save_button), have_unsaved_capture_file);
131 gtk_widget_set_sensitive(GTK_WIDGET(save_as_button), !have_unsaved_capture_file);*/
135 /* fudge to call correct file_save or file_save_as fcn based upon the
136 value of the "save" key associated with the save button
139 static void file_save_or_save_as_cmd_cb(GtkWidget *w, gpointer data) {
140 if (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(save_button),"save")) == 1) {
141 file_save_cmd_cb(w, data);
144 file_save_as_cmd_cb(w, data);
148 /** The packet history has changed, we need to update the menu.
150 * @param back_history some back history entries available
151 * @param forward_history some forward history entries available
153 void set_toolbar_for_packet_history(gboolean back_history, gboolean forward_history) {
154 gtk_widget_set_sensitive(GTK_WIDGET(history_back_button), back_history);
155 gtk_widget_set_sensitive(GTK_WIDGET(history_forward_button), forward_history);
159 /* set toolbar state "have a capture in progress" */
160 void set_toolbar_for_capture_in_progress(gboolean capture_in_progress) {
164 gtk_widget_set_sensitive(GTK_WIDGET(capture_options_button), !capture_in_progress);
165 gtk_widget_set_sensitive(GTK_WIDGET(new_button), !capture_in_progress);
166 gtk_widget_set_sensitive(GTK_WIDGET(stop_button), capture_in_progress);
167 gtk_widget_set_sensitive(GTK_WIDGET(clear_button), capture_in_progress);
168 /*if (capture_in_progress) {
169 gtk_widget_hide(GTK_WIDGET(new_button));
170 gtk_widget_show(GTK_WIDGET(stop_button));
172 gtk_widget_show(GTK_WIDGET(new_button));
173 gtk_widget_hide(GTK_WIDGET(stop_button));
175 #endif /* HAVE_LIBPCAP */
176 gtk_widget_set_sensitive(GTK_WIDGET(open_button), !capture_in_progress);
180 /* set toolbar state "have packets captured" */
181 void set_toolbar_for_captured_packets(gboolean have_captured_packets) {
184 gtk_widget_set_sensitive(GTK_WIDGET(print_button),
185 have_captured_packets);
186 gtk_widget_set_sensitive(GTK_WIDGET(find_button),
187 have_captured_packets);
188 gtk_widget_set_sensitive(GTK_WIDGET(history_back_button),
189 have_captured_packets);
190 gtk_widget_set_sensitive(GTK_WIDGET(history_forward_button),
191 have_captured_packets);
192 gtk_widget_set_sensitive(GTK_WIDGET(go_to_button),
193 have_captured_packets);
194 gtk_widget_set_sensitive(GTK_WIDGET(go_to_top_button),
195 have_captured_packets);
196 gtk_widget_set_sensitive(GTK_WIDGET(go_to_bottom_button),
197 have_captured_packets);
198 gtk_widget_set_sensitive(GTK_WIDGET(zoom_in_button),
199 have_captured_packets);
200 gtk_widget_set_sensitive(GTK_WIDGET(zoom_out_button),
201 have_captured_packets);
202 gtk_widget_set_sensitive(GTK_WIDGET(zoom_100_button),
203 have_captured_packets);
204 gtk_widget_set_sensitive(GTK_WIDGET(resize_columns_button),
205 have_captured_packets);
207 /* XXX - I don't see a reason why this should be done (as it is in the
209 /* gtk_widget_set_sensitive(GTK_WIDGET(color_display_button),
210 have_captured_packets);*/
215 /* helper function: add a separator to the toolbar */
216 static void toolbar_append_separator(GtkWidget *toolbar) {
217 GtkToolItem *tool_item = gtk_separator_tool_item_new();
218 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), tool_item, -1);
219 gtk_widget_show(GTK_WIDGET(tool_item));
224 #define toolbar_item(new_item, toolbar, stock, tooltip_text, callback, user_data) { \
225 new_item = gtk_tool_button_new_from_stock(stock); \
226 gtk_widget_set_tooltip_text(GTK_WIDGET(new_item), tooltip_text); \
227 g_signal_connect(new_item, "clicked", G_CALLBACK(callback), user_data); \
228 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), new_item, -1); \
229 gtk_widget_show(GTK_WIDGET(new_item)); \
232 #define toolbar_toggle_button(new_item, window, toolbar, stock, tooltip_text, callback, user_data) { \
233 new_item = gtk_toggle_tool_button_new_from_stock(stock); \
234 gtk_widget_set_tooltip_text(GTK_WIDGET(new_item), tooltip_text); \
235 g_signal_connect(new_item, "toggled", G_CALLBACK(callback), user_data); \
236 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), new_item, -1); \
237 gtk_widget_show_all(GTK_WIDGET(new_item)); \
240 #define TOGGLE_BUTTON GTK_TOGGLE_TOOL_BUTTON
241 #define TOGGLE_BUTTON_GET_ACTIVE gtk_toggle_tool_button_get_active
242 #define TOGGLE_BUTTON_SET_ACTIVE gtk_toggle_tool_button_set_active
245 colorize_toggle_cb(GtkWidget *toggle_button, gpointer user_data _U_) {
246 menu_colorize_changed(TOGGLE_BUTTON_GET_ACTIVE(TOGGLE_BUTTON(toggle_button)));
250 toolbar_colorize_changed(gboolean packet_list_colorize) {
251 if(TOGGLE_BUTTON_GET_ACTIVE(TOGGLE_BUTTON(colorize_button)) != packet_list_colorize) {
252 TOGGLE_BUTTON_SET_ACTIVE(TOGGLE_BUTTON(colorize_button), packet_list_colorize);
258 auto_scroll_live_toggle_cb(GtkWidget *autoscroll_button_lcl, gpointer user_data _U_) {
259 menu_auto_scroll_live_changed(TOGGLE_BUTTON_GET_ACTIVE(TOGGLE_BUTTON(autoscroll_button_lcl)));
263 toolbar_auto_scroll_live_changed(gboolean auto_scroll_live_lcl) {
264 if(TOGGLE_BUTTON_GET_ACTIVE(TOGGLE_BUTTON(autoscroll_button)) != auto_scroll_live_lcl) {
265 TOGGLE_BUTTON_SET_ACTIVE(TOGGLE_BUTTON(autoscroll_button), auto_scroll_live_lcl);
272 * Create all toolbars (currently only the main toolbar)
278 GtkWidget *window = top_level;
280 /* this function should be only called once! */
281 g_assert(!toolbar_init);
283 /* we need to realize the window because we use pixmaps for
284 * items on the toolbar in the context of it */
285 /* (coming from the gtk example, please don't ask me why ;-) */
286 gtk_widget_realize(window);
288 /* toolbar will be horizontal, with both icons and text (as default here) */
289 /* (this will usually be overwritten by the preferences setting) */
290 main_tb = gtk_toolbar_new();
291 gtk_orientable_set_orientation(GTK_ORIENTABLE(main_tb),
292 GTK_ORIENTATION_HORIZONTAL);
294 g_object_set_data(G_OBJECT(top_level), E_TB_MAIN_KEY, main_tb);
298 toolbar_item(if_button, main_tb,
299 WIRESHARK_STOCK_CAPTURE_INTERFACES, "List the available capture interfaces...", capture_if_cb, NULL);
301 toolbar_item(capture_options_button, main_tb,
302 WIRESHARK_STOCK_CAPTURE_OPTIONS, "Show the capture options...", capture_prep_cb, NULL);
304 toolbar_item(new_button, main_tb,
305 WIRESHARK_STOCK_CAPTURE_START, "Start a new live capture", capture_start_cb, NULL);
307 toolbar_item(stop_button, main_tb,
308 WIRESHARK_STOCK_CAPTURE_STOP, "Stop the running live capture", capture_stop_cb, NULL);
310 toolbar_item(clear_button, main_tb,
311 WIRESHARK_STOCK_CAPTURE_RESTART, "Restart the running live capture", capture_restart_cb, NULL);
313 toolbar_append_separator(main_tb);
314 #endif /* HAVE_LIBPCAP */
316 toolbar_item(open_button, main_tb,
317 GTK_STOCK_OPEN, "Open a capture file...", file_open_cmd_cb, NULL);
319 /* Only create a separate button in GTK < 2.4. With GTK 2.4+, we will
320 * just modify the save_button to read/show save or save as as needed.
321 * We'll also fudge in an object key ("save") for the save button with data which specifies
322 * whether the button is currently "save" (1)or "save as" (0).
323 * The fcn file_save_or_save_as_cmd_cb
324 * will then call the appropriate file_save_cmd_cb or file_save_as_cmd_cb
327 toolbar_item(save_button, main_tb,
328 GTK_STOCK_SAVE, SAVE_BUTTON_TOOLTIP_TEXT, file_save_or_save_as_cmd_cb, NULL);
329 g_object_set_data(G_OBJECT(save_button), "save", GINT_TO_POINTER(1));
331 toolbar_item(close_button, main_tb,
332 GTK_STOCK_CLOSE, "Close this capture file", file_close_cmd_cb, NULL);
334 toolbar_item(reload_button, main_tb,
335 GTK_STOCK_REFRESH, "Reload this capture file", file_reload_cmd_cb, NULL);
337 toolbar_item(print_button, main_tb,
338 GTK_STOCK_PRINT, "Print packet(s)...", file_print_cmd_cb, NULL);
340 toolbar_append_separator(main_tb);
342 toolbar_item(find_button, main_tb,
343 GTK_STOCK_FIND, "Find a packet...", find_frame_cb, NULL);
345 toolbar_item(history_back_button, main_tb,
346 GTK_STOCK_GO_BACK, "Go back in packet history", history_back_cb, NULL);
348 toolbar_item(history_forward_button, main_tb,
349 GTK_STOCK_GO_FORWARD, "Go forward in packet history", history_forward_cb, NULL);
351 toolbar_item(go_to_button, main_tb,
352 GTK_STOCK_JUMP_TO, "Go to the packet with number...", goto_frame_cb, NULL);
354 toolbar_item(go_to_top_button, main_tb,
355 GTK_STOCK_GOTO_TOP, "Go to the first packet", goto_top_frame_cb, NULL);
357 toolbar_item(go_to_bottom_button, main_tb,
358 GTK_STOCK_GOTO_BOTTOM, "Go to the last packet", goto_bottom_frame_cb, NULL);
360 toolbar_append_separator(main_tb);
362 toolbar_toggle_button(colorize_button, window, main_tb,
363 WIRESHARK_STOCK_COLORIZE, "Colorize Packet List", colorize_toggle_cb, NULL);
366 toolbar_toggle_button(autoscroll_button, window, main_tb,
367 WIRESHARK_STOCK_AUTOSCROLL, "Auto Scroll Packet List in Live Capture", auto_scroll_live_toggle_cb, NULL);
370 toolbar_append_separator(main_tb);
372 toolbar_item(zoom_in_button, main_tb,
373 GTK_STOCK_ZOOM_IN, "Zoom in", view_zoom_in_cb, NULL);
375 toolbar_item(zoom_out_button, main_tb,
376 GTK_STOCK_ZOOM_OUT, "Zoom out", view_zoom_out_cb, NULL);
378 toolbar_item(zoom_100_button, main_tb,
379 GTK_STOCK_ZOOM_100, "Zoom 100%", view_zoom_100_cb, NULL);
381 toolbar_item(resize_columns_button, main_tb,
382 WIRESHARK_STOCK_RESIZE_COLUMNS, "Resize All Columns", new_packet_list_resize_columns_cb, NULL);
384 toolbar_append_separator(main_tb);
387 toolbar_item(capture_filter_button, main_tb,
388 WIRESHARK_STOCK_CAPTURE_FILTER, "Edit capture filter...", cfilter_dialog_cb, NULL);
389 #endif /* HAVE_LIBPCAP */
391 toolbar_item(display_filter_button, main_tb,
392 WIRESHARK_STOCK_DISPLAY_FILTER, "Edit/apply display filter...", dfilter_dialog_cb, NULL);
394 toolbar_item(color_display_button, main_tb,
395 GTK_STOCK_SELECT_COLOR, "Edit coloring rules...", color_display_cb, NULL);
397 /* the preference button uses it's own Stock icon label "Prefs", as "Preferences" is too long */
398 toolbar_item(prefs_button, main_tb,
399 GTK_STOCK_PREFERENCES, "Edit preferences...", prefs_cb, NULL);
401 toolbar_append_separator(main_tb);
403 toolbar_item(help_button, main_tb,
404 GTK_STOCK_HELP, "Show some help...", topic_cb, GINT_TO_POINTER(HELP_CONTENT));
406 /* disable all "sensitive" items by default */
408 set_toolbar_for_unsaved_capture_file(FALSE);
409 set_toolbar_for_captured_packets(FALSE);
410 set_toolbar_for_capture_file(FALSE);
412 set_toolbar_for_capture_in_progress(FALSE);
413 #endif /* HAVE_LIBPCAP */
415 /* make current preferences effective */
416 toolbar_redraw_all();
422 set_toolbar_object_data(gchar *key, gpointer data)
424 g_object_set_data(G_OBJECT(open_button), key, data);
425 g_object_set_data(G_OBJECT(reload_button), key, data);