/* toolbar.c * The main toolbar * Copyright 2003, Ulf Lamping * * $Id$ * * Wireshark - Network traffic analyzer * By Gerald Combs * Copyright 1998 Gerald Combs * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* * This file implements the "main" toolbar for Wireshark. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #ifdef HAVE_LIBPCAP #include "capture_dlg.h" #endif /* HAVE_LIBPCAP */ #include "filter_dlg.h" #include "capture_file_dlg.h" #include "find_dlg.h" #include "goto_dlg.h" #include "color.h" #include "color_dlg.h" #include #include "prefs_dlg.h" #include "main.h" #include "main_menu.h" #include "main_toolbar.h" #include "help_dlg.h" #include "gtkglobals.h" #include "stock_icons.h" #include "keys.h" #include "recent.h" #include "packet_history.h" #include "packet_list.h" #include "color_filters.h" /* XXX: add this key to some .h file, as it adds a key to the top level Widget? */ #define E_TB_MAIN_KEY "toolbar_main" static gboolean toolbar_init = FALSE; #if GTK_CHECK_VERSION(2,4,0) #define BUTTON_TYPE GtkToolItem #else /* GTK_CHECK_VERSION(2,4,0) */ #define BUTTON_TYPE GtkWidget #endif /* GTK_CHECK_VERSION(2,4,0) */ #ifdef HAVE_LIBPCAP static BUTTON_TYPE *capture_options_button, *new_button, *stop_button, *clear_button, *if_button; static BUTTON_TYPE *capture_filter_button, *autoscroll_button; #endif /* HAVE_LIBPCAP */ static BUTTON_TYPE *open_button, *save_button, *close_button, *reload_button; static BUTTON_TYPE *print_button, *find_button, *history_forward_button, *history_back_button; static BUTTON_TYPE *go_to_button, *go_to_top_button, *go_to_bottom_button; static BUTTON_TYPE *display_filter_button; static BUTTON_TYPE *zoom_in_button, *zoom_out_button, *zoom_100_button, *colorize_button, *resize_columns_button; static BUTTON_TYPE *color_display_button, *prefs_button, *help_button; #if !GTK_CHECK_VERSION(2,4,0) static BUTTON_TYPE *save_as_button; #endif #define SAVE_BUTTON_TOOLTIP_TEXT "Save this capture file..." #define SAVE_AS_BUTTON_TOOLTIP_TEXT "Save this capture file as..." /* * Redraw all toolbars (currently only the main toolbar) */ void toolbar_redraw_all(void) { GtkWidget *main_tb; main_tb = g_object_get_data(G_OBJECT(top_level), E_TB_MAIN_KEY); gtk_toolbar_set_style(GTK_TOOLBAR(main_tb), prefs.gui_toolbar_main_style); } /* Enable or disable toolbar items based on whether you have a capture file you've finished reading. */ void set_toolbar_for_capture_file(gboolean have_capture_file) { if (toolbar_init) { gtk_widget_set_sensitive(GTK_WIDGET(save_button), have_capture_file); #if !GTK_CHECK_VERSION(2,4,0) gtk_widget_set_sensitive(GTK_WIDGET(save_as_button), have_capture_file); #endif gtk_widget_set_sensitive(GTK_WIDGET(close_button), have_capture_file); gtk_widget_set_sensitive(GTK_WIDGET(reload_button), have_capture_file); } } /* Enable or disable menu items based on whether you have an unsaved capture file you've finished reading. */ void set_toolbar_for_unsaved_capture_file(gboolean have_unsaved_capture_file) { GtkTooltips *tooltips; tooltips = gtk_tooltips_new(); if (toolbar_init) { if(have_unsaved_capture_file) { #if GTK_CHECK_VERSION(2,4,0) gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(save_button), GTK_STOCK_SAVE); gtk_tool_item_set_tooltip(save_button, tooltips, SAVE_BUTTON_TOOLTIP_TEXT, NULL); g_object_set_data(G_OBJECT(save_button), "save", GINT_TO_POINTER(1)); #else /* GTK_CHECK_VERSION(2,4,0) */ gtk_widget_hide(GTK_WIDGET(save_as_button)); gtk_widget_show(GTK_WIDGET(save_button)); #endif /* GTK_CHECK_VERSION(2,4,0) */ } else { #if GTK_CHECK_VERSION(2,4,0) gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(save_button), GTK_STOCK_SAVE_AS); gtk_tool_item_set_tooltip(save_button, tooltips, SAVE_AS_BUTTON_TOOLTIP_TEXT, NULL); g_object_set_data(G_OBJECT(save_button), "save", GINT_TO_POINTER(0)); #else /* GTK_CHECK_VERSION(2,4,0) */ gtk_widget_show(GTK_WIDGET(save_as_button)); gtk_widget_hide(GTK_WIDGET(save_button)); #endif /* GTK_CHECK_VERSION(2,4,0) */ } /*gtk_widget_set_sensitive((GTK_WIDGET(save_button), have_unsaved_capture_file); gtk_widget_set_sensitive(GTK_WIDGET(save_as_button), !have_unsaved_capture_file);*/ } } /* fudge to call correct file_save or file_save_as fcn based upon the value of the "save" key associated with the save button */ #if GTK_CHECK_VERSION(2,4,0) static void file_save_or_save_as_cmd_cb(GtkWidget *w, gpointer data) { if (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(save_button),"save")) == 1) { file_save_cmd_cb(w, data); } else { file_save_as_cmd_cb(w, data); } } #endif /** The packet history has changed, we need to update the menu. * * @param back_history some back history entries available * @param forward_history some forward history entries available */ void set_toolbar_for_packet_history(gboolean back_history, gboolean forward_history) { gtk_widget_set_sensitive(GTK_WIDGET(history_back_button), back_history); gtk_widget_set_sensitive(GTK_WIDGET(history_forward_button), forward_history); } /* set toolbar state "have a capture in progress" */ void set_toolbar_for_capture_in_progress(gboolean capture_in_progress) { if (toolbar_init) { #ifdef HAVE_LIBPCAP gtk_widget_set_sensitive(GTK_WIDGET(capture_options_button), !capture_in_progress); gtk_widget_set_sensitive(GTK_WIDGET(new_button), !capture_in_progress); gtk_widget_set_sensitive(GTK_WIDGET(stop_button), capture_in_progress); gtk_widget_set_sensitive(GTK_WIDGET(clear_button), capture_in_progress); /*if (capture_in_progress) { gtk_widget_hide(GTK_WIDGET(new_button)); gtk_widget_show(GTK_WIDGET(stop_button)); } else { gtk_widget_show(GTK_WIDGET(new_button)); gtk_widget_hide(GTK_WIDGET(stop_button)); }*/ #endif /* HAVE_LIBPCAP */ gtk_widget_set_sensitive(GTK_WIDGET(open_button), !capture_in_progress); } } /* set toolbar state "have packets captured" */ void set_toolbar_for_captured_packets(gboolean have_captured_packets) { if (toolbar_init) { gtk_widget_set_sensitive(GTK_WIDGET(print_button), have_captured_packets); gtk_widget_set_sensitive(GTK_WIDGET(find_button), have_captured_packets); gtk_widget_set_sensitive(GTK_WIDGET(history_back_button), have_captured_packets); gtk_widget_set_sensitive(GTK_WIDGET(history_forward_button), have_captured_packets); gtk_widget_set_sensitive(GTK_WIDGET(go_to_button), have_captured_packets); gtk_widget_set_sensitive(GTK_WIDGET(go_to_top_button), have_captured_packets); gtk_widget_set_sensitive(GTK_WIDGET(go_to_bottom_button), have_captured_packets); gtk_widget_set_sensitive(GTK_WIDGET(zoom_in_button), have_captured_packets); gtk_widget_set_sensitive(GTK_WIDGET(zoom_out_button), have_captured_packets); gtk_widget_set_sensitive(GTK_WIDGET(zoom_100_button), have_captured_packets); gtk_widget_set_sensitive(GTK_WIDGET(resize_columns_button), have_captured_packets); /* XXX - I don't see a reason why this should be done (as it is in the * menus) */ /* gtk_widget_set_sensitive(GTK_WIDGET(color_display_button), have_captured_packets);*/ } } /* helper function: add a separator to the toolbar */ static void toolbar_append_separator(GtkWidget *toolbar) { #if GTK_CHECK_VERSION(2,4,0) GtkToolItem *tool_item = gtk_separator_tool_item_new(); gtk_toolbar_insert(GTK_TOOLBAR(toolbar), tool_item, -1); gtk_widget_show(GTK_WIDGET(tool_item)); #else /* GTK_CHECK_VERSION(2,4,0) */ /* GTK 2 uses (as it should be) a seperator when adding this space */ gtk_toolbar_append_space(GTK_TOOLBAR(toolbar)); #endif /* GTK_CHECK_VERSION(2,4,0) */ } #if GTK_CHECK_VERSION(2,4,0) #define toolbar_item(new_item, window, toolbar, stock, tooltips, tooltip_text, xpm, callback, user_data) { \ new_item = gtk_tool_button_new_from_stock(stock); \ gtk_tool_item_set_tooltip(new_item, tooltips, tooltip_text, NULL); \ g_signal_connect(new_item, "clicked", G_CALLBACK(callback), user_data); \ gtk_toolbar_insert(GTK_TOOLBAR(toolbar), new_item, -1); \ gtk_widget_show(GTK_WIDGET(new_item)); \ } #else /* GTK_CHECK_VERSION(2,4,0) */ #define toolbar_item(new_item, window, toolbar, stock, tooltips, tooltip_text, xpm, callback, user_data) { \ new_item = gtk_toolbar_insert_stock(GTK_TOOLBAR(toolbar), \ stock, tooltip_text, "Private", G_CALLBACK(callback), user_data, -1);\ } #endif /* GTK_CHECK_VERSION(2,4,0) */ #define toolbar_icon(new_icon, window, xpm) { \ icon = gdk_pixmap_create_from_xpm_d(window->window, &mask, &window->style->white, (gchar **) xpm); \ new_icon = gtk_image_new_from_pixmap(icon, mask); \ } #if GTK_CHECK_VERSION(2,4,0) #define toolbar_toggle_button(new_item, window, toolbar, stock, tooltips, tooltip_text, xpm, callback, user_data) { \ new_item = gtk_toggle_tool_button_new_from_stock(stock); \ gtk_tool_item_set_tooltip(new_item, tooltips, tooltip_text, NULL); \ g_signal_connect(new_item, "toggled", G_CALLBACK(callback), user_data); \ gtk_toolbar_insert(GTK_TOOLBAR(toolbar), new_item, -1); \ gtk_widget_show_all(GTK_WIDGET(new_item)); \ } #else /* GTK_CHECK_VERSION(2,4,0) */ #define toolbar_toggle_button(new_item, window, toolbar, stock, tooltips, tooltip_text, xpm, callback, user_data) { \ toolbar_icon(iconw, window, xpm); \ new_item = gtk_toolbar_append_element(GTK_TOOLBAR(toolbar), \ GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL, \ stock, tooltip_text, "Private", iconw, GTK_SIGNAL_FUNC(callback), user_data);\ } #endif /* GTK_CHECK_VERSION(2,4,0) */ static void colorize_toggle_cb(GtkWidget *toggle_button, gpointer user_data _U_) { #if GTK_CHECK_VERSION(2,4,0) menu_colorize_changed(gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(toggle_button))); #else /* GTK_CHECK_VERSION(2,4,0) */ menu_colorize_changed(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle_button))); #endif /* GTK_CHECK_VERSION(2,4,0) */ } void toolbar_colorize_changed(gboolean packet_list_colorize) { #if GTK_CHECK_VERSION(2,4,0) if(gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(colorize_button)) != packet_list_colorize) { gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(colorize_button), packet_list_colorize); } #else /* GTK_CHECK_VERSION(2,4,0) */ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(colorize_button)) != packet_list_colorize) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(colorize_button), packet_list_colorize); } #endif /* GTK_CHECK_VERSION(2,4,0) */ } #ifdef HAVE_LIBPCAP static void auto_scroll_live_toggle_cb(GtkWidget *autoscroll_button, gpointer user_data _U_) { #if GTK_CHECK_VERSION(2,4,0) menu_auto_scroll_live_changed(gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(autoscroll_button))); #else /* GTK_CHECK_VERSION(2,4,0) */ menu_auto_scroll_live_changed(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(autoscroll_button))); #endif /* GTK_CHECK_VERSION(2,4,0) */ } void toolbar_auto_scroll_live_changed(gboolean auto_scroll_live) { #if GTK_CHECK_VERSION(2,4,0) if(gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(autoscroll_button)) != auto_scroll_live) { gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(autoscroll_button), auto_scroll_live); } #else /* GTK_CHECK_VERSION(2,4,0) */ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(autoscroll_button)) != auto_scroll_live) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(autoscroll_button), auto_scroll_live); } #endif /* GTK_CHECK_VERSION(2,4,0) */ } #endif /* * Create all toolbars (currently only the main toolbar) */ GtkWidget * toolbar_new(void) { GtkWidget *main_tb; GtkWidget *window = top_level; #if !GTK_CHECK_VERSION(2,4,0) GdkPixmap *icon; GdkBitmap * mask; GtkWidget *iconw; #endif GtkTooltips *tooltips; tooltips = gtk_tooltips_new(); /* this function should be only called once! */ g_assert(!toolbar_init); /* we need to realize the window because we use pixmaps for * items on the toolbar in the context of it */ /* (coming from the gtk example, please don't ask me why ;-) */ gtk_widget_realize(window); /* toolbar will be horizontal, with both icons and text (as default here) */ /* (this will usually be overwritten by the preferences setting) */ main_tb = gtk_toolbar_new(); gtk_toolbar_set_orientation(GTK_TOOLBAR(main_tb), GTK_ORIENTATION_HORIZONTAL); g_object_set_data(G_OBJECT(top_level), E_TB_MAIN_KEY, main_tb); #ifdef HAVE_LIBPCAP toolbar_item(if_button, window, main_tb, WIRESHARK_STOCK_CAPTURE_INTERFACES, tooltips, "List the available capture interfaces...", capture_interfaces_24_xpm, capture_if_cb, NULL); toolbar_item(capture_options_button, window, main_tb, WIRESHARK_STOCK_CAPTURE_OPTIONS, tooltips, "Show the capture options...", capture_options_24_xpm, capture_prep_cb, NULL); toolbar_item(new_button, window, main_tb, WIRESHARK_STOCK_CAPTURE_START, tooltips, "Start a new live capture", capture_start_24_xpm, capture_start_cb, NULL); toolbar_item(stop_button, window, main_tb, WIRESHARK_STOCK_CAPTURE_STOP, tooltips, "Stop the running live capture", capture_stop_24_xpm, capture_stop_cb, NULL); toolbar_item(clear_button, window, main_tb, WIRESHARK_STOCK_CAPTURE_RESTART, tooltips, "Restart the running live capture", capture_restart_24_xpm, capture_restart_cb, NULL); toolbar_append_separator(main_tb); #endif /* HAVE_LIBPCAP */ toolbar_item(open_button, window, main_tb, GTK_STOCK_OPEN, tooltips, "Open a capture file...", stock_open_24_xpm, file_open_cmd_cb, NULL); /* Only create a separate button in GTK < 2.4. With GTK 2.4+, we will * just modify the save_button to read/show save or save as as needed. * We'll also fudge in an object key ("save") for the save button with data which specifies * whether the button is currently "save" (1)or "save as" (0). * The fcn file_save_or_save_as_cmd_cb * will then call the appropriate file_save_cmd_cb or file_save_as_cmd_cb */ #if !GTK_CHECK_VERSION(2,4,0) toolbar_item(save_button, window, main_tb, GTK_STOCK_SAVE, tooltips, SAVE_BUTTON_TOOLTIP_TEXT, stock_save_24_xpm, file_save_cmd_cb, NULL); toolbar_item(save_as_button, window, main_tb, GTK_STOCK_SAVE_AS, tooltips, SAVE_AS_BUTTON_TOOLTIP_TEXT, stock_save_as_24_xpm, file_save_as_cmd_cb, NULL); #else toolbar_item(save_button, window, main_tb, GTK_STOCK_SAVE, tooltips, SAVE_BUTTON_TOOLTIP_TEXT, stock_save_24_xpm, file_save_or_save_as_cmd_cb, NULL); g_object_set_data(G_OBJECT(save_button), "save", GINT_TO_POINTER(1)); #endif toolbar_item(close_button, window, main_tb, GTK_STOCK_CLOSE, tooltips, "Close this capture file", stock_close_24_xpm, file_close_cmd_cb, NULL); toolbar_item(reload_button, window, main_tb, GTK_STOCK_REFRESH, tooltips, "Reload this capture file", stock_refresh_24_xpm, file_reload_cmd_cb, NULL); toolbar_item(print_button, window, main_tb, GTK_STOCK_PRINT, tooltips, "Print packet(s)...", stock_print_24_xpm, file_print_cmd_cb, NULL); toolbar_append_separator(main_tb); toolbar_item(find_button, window, main_tb, GTK_STOCK_FIND, tooltips, "Find a packet...", stock_search_24_xpm, find_frame_cb, NULL); toolbar_item(history_back_button, window, main_tb, GTK_STOCK_GO_BACK, tooltips, "Go back in packet history", stock_left_arrow_24_xpm, history_back_cb, NULL); toolbar_item(history_forward_button, window, main_tb, GTK_STOCK_GO_FORWARD, tooltips, "Go forward in packet history", stock_right_arrow_24_xpm, history_forward_cb, NULL); toolbar_item(go_to_button, window, main_tb, GTK_STOCK_JUMP_TO, tooltips, "Go to the packet with number...", stock_jump_to_24_xpm, goto_frame_cb, NULL); toolbar_item(go_to_top_button, window, main_tb, GTK_STOCK_GOTO_TOP, tooltips, "Go to the first packet", stock_top_24_xpm, goto_top_frame_cb, NULL); toolbar_item(go_to_bottom_button, window, main_tb, GTK_STOCK_GOTO_BOTTOM, tooltips, "Go to the last packet", stock_bottom_24_xpm, goto_bottom_frame_cb, NULL); toolbar_append_separator(main_tb); toolbar_toggle_button(colorize_button, window, main_tb, WIRESHARK_STOCK_COLORIZE, tooltips, "Colorize Packet List", colorize_24_xpm, colorize_toggle_cb, NULL); #ifdef HAVE_LIBPCAP toolbar_toggle_button(autoscroll_button, window, main_tb, WIRESHARK_STOCK_AUTOSCROLL, tooltips, "Auto Scroll Packet List in Live Capture", autoscroll_24_xpm, auto_scroll_live_toggle_cb, NULL); #endif toolbar_append_separator(main_tb); toolbar_item(zoom_in_button, window, main_tb, GTK_STOCK_ZOOM_IN, tooltips, "Zoom in", stock_zoom_in_24_xpm, view_zoom_in_cb, NULL); toolbar_item(zoom_out_button, window, main_tb, GTK_STOCK_ZOOM_OUT, tooltips, "Zoom out", stock_zoom_out_24_xpm, view_zoom_out_cb, NULL); toolbar_item(zoom_100_button, window, main_tb, GTK_STOCK_ZOOM_100, tooltips, "Zoom 100%", stock_zoom_1_24_xpm, view_zoom_100_cb, NULL); toolbar_item(resize_columns_button, window, main_tb, WIRESHARK_STOCK_RESIZE_COLUMNS, tooltips, "Resize All Columns", resize_columns_24_xpm, packet_list_resize_columns_cb, NULL); toolbar_append_separator(main_tb); #ifdef HAVE_LIBPCAP toolbar_item(capture_filter_button, window, main_tb, WIRESHARK_STOCK_CAPTURE_FILTER, tooltips, "Edit capture filter...", capture_filter_24_xpm, cfilter_dialog_cb, NULL); #endif /* HAVE_LIBPCAP */ toolbar_item(display_filter_button, window, main_tb, WIRESHARK_STOCK_DISPLAY_FILTER, tooltips, "Edit/apply display filter...", display_filter_24_xpm, dfilter_dialog_cb, NULL); toolbar_item(color_display_button, window, main_tb, GTK_STOCK_SELECT_COLOR, tooltips, "Edit coloring rules...", stock_colorselector_24_xpm, color_display_cb, NULL); /* the preference button uses it's own Stock icon label "Prefs", as "Preferences" is too long */ toolbar_item(prefs_button, window, main_tb, GTK_STOCK_PREFERENCES, tooltips, "Edit preferences...", stock_preferences_24_xpm, prefs_cb, NULL); toolbar_append_separator(main_tb); toolbar_item(help_button, window, main_tb, GTK_STOCK_HELP, tooltips, "Show some help...", stock_help_24_xpm, topic_cb, GINT_TO_POINTER(HELP_CONTENT)); /* disable all "sensitive" items by default */ toolbar_init = TRUE; set_toolbar_for_unsaved_capture_file(FALSE); set_toolbar_for_captured_packets(FALSE); set_toolbar_for_capture_file(FALSE); #ifdef HAVE_LIBPCAP set_toolbar_for_capture_in_progress(FALSE); #endif /* HAVE_LIBPCAP */ /* make current preferences effective */ toolbar_redraw_all(); return main_tb; } void set_toolbar_object_data(gchar *key, gpointer data) { g_object_set_data(G_OBJECT(open_button), key, data); g_object_set_data(G_OBJECT(reload_button), key, data); }