/* layout_prefs.c * Dialog box for layout preferences * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include "cfile.h" #include "ui/ui_util.h" #include "ui/gtk/prefs_layout.h" #include "ui/gtk/gtkglobals.h" #include "ui/gtk/prefs_dlg.h" #include "ui/gtk/main_titlebar.h" #include "ui/gtk/gui_utils.h" #include "ui/gtk/main.h" #include "ui/gtk/dlg_utils.h" #include "layouts.h" #define LAYOUT_QTY (layout_type_max - 1) static void layout_validate_cb(GtkWidget *rb, gpointer data); static gint fetch_enum_value(gpointer control, const enum_val_t *enumvals); typedef struct { layout_type_e type; layout_pane_content_e content[3]; } layout_t; #define LAYOUT_TYPE_BUTTONS_KEY "layout_type_buttons" #define LAYOUT_NONE_RB_KEY "layout_none_radio_button" #define LAYOUT_PLIST_RB_KEY "layout_plist_radio_button" #define LAYOUT_PDETAILS_RB_KEY "layout_pdetails_radio_button" #define LAYOUT_PBYTES_RB_KEY "layout_pbytes_radio_button" #define LAYOUT_CONTENT1_VB_KEY "layout_content1_vbox" #define LAYOUT_CONTENT2_VB_KEY "layout_content2_vbox" #define LAYOUT_CONTENT3_VB_KEY "layout_content3_vbox" #define LAYOUT_PANE_KEY "layout_pane" static GtkWidget *layout_content_radio_vbox(GtkWidget *main_vb, int i, layout_pane_content_e content) { GtkWidget *radio_vb, *radio_lb; GtkWidget *radio_none_rb, *radio_plist_rb, *radio_pdetails_rb, *radio_pbytes_rb; char buf[64]; /* radio vbox */ radio_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE); gtk_container_set_border_width(GTK_CONTAINER(radio_vb), 6); g_snprintf (buf, sizeof(buf), "Pane %d:", i); radio_lb = gtk_label_new(buf); gtk_misc_set_alignment(GTK_MISC(radio_lb), 0.0f, 0.5f); gtk_container_add(GTK_CONTAINER(radio_vb), radio_lb); radio_plist_rb = gtk_radio_button_new_with_mnemonic_from_widget(NULL, "Packet List"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_plist_rb), content == layout_pane_content_plist); gtk_widget_set_tooltip_text (radio_plist_rb, "Put the packet list in this pane."); gtk_container_add(GTK_CONTAINER(radio_vb), radio_plist_rb); radio_pdetails_rb = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(radio_plist_rb), "Packet Details"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_pdetails_rb), content == layout_pane_content_pdetails); gtk_widget_set_tooltip_text (radio_pdetails_rb, "Put the packet details tree in this pane."); gtk_container_add(GTK_CONTAINER(radio_vb), radio_pdetails_rb); radio_pbytes_rb = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(radio_plist_rb), "Packet Bytes"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_pbytes_rb), content == layout_pane_content_pbytes); gtk_widget_set_tooltip_text (radio_pbytes_rb, "Put the packet bytes dump in this pane."); gtk_container_add(GTK_CONTAINER(radio_vb), radio_pbytes_rb); radio_none_rb = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(radio_plist_rb), "None"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_none_rb), content == layout_pane_content_none); gtk_widget_set_tooltip_text (radio_none_rb, "Put nothing in this pane."); gtk_container_add(GTK_CONTAINER(radio_vb), radio_none_rb); g_object_set_data(G_OBJECT(radio_vb), LAYOUT_PLIST_RB_KEY, radio_plist_rb); g_object_set_data(G_OBJECT(radio_vb), LAYOUT_PDETAILS_RB_KEY, radio_pdetails_rb); g_object_set_data(G_OBJECT(radio_vb), LAYOUT_PBYTES_RB_KEY, radio_pbytes_rb); g_object_set_data(G_OBJECT(radio_vb), LAYOUT_NONE_RB_KEY, radio_none_rb); g_object_set_data(G_OBJECT(radio_plist_rb), LAYOUT_PANE_KEY, GINT_TO_POINTER(i)); g_object_set_data(G_OBJECT(radio_pdetails_rb), LAYOUT_PANE_KEY, GINT_TO_POINTER(i)); g_object_set_data(G_OBJECT(radio_pbytes_rb), LAYOUT_PANE_KEY, GINT_TO_POINTER(i)); g_object_set_data(G_OBJECT(radio_none_rb), LAYOUT_PANE_KEY, GINT_TO_POINTER(-1)); g_signal_connect(radio_plist_rb, "toggled", G_CALLBACK(layout_validate_cb), main_vb); g_signal_connect(radio_pdetails_rb, "toggled", G_CALLBACK(layout_validate_cb), main_vb); g_signal_connect(radio_pbytes_rb, "toggled", G_CALLBACK(layout_validate_cb), main_vb); g_signal_connect(radio_none_rb, "toggled", G_CALLBACK(layout_validate_cb), main_vb); return radio_vb; } static void layout_type_changed_cb (GtkToggleButton * togglebutton, gpointer user_data) { GtkWidget ** layout_type_buttons = (GtkWidget**) user_data; static gboolean dampen_feedback_loop = FALSE; if (!dampen_feedback_loop) { int i; dampen_feedback_loop = TRUE; for (i=0; itype - 1]), TRUE); radio_vb = (GtkWidget *)g_object_get_data(G_OBJECT(main_vb), LAYOUT_CONTENT1_VB_KEY); layout_pane_set_content(radio_vb, layout->content[0]); radio_vb = (GtkWidget *)g_object_get_data(G_OBJECT(main_vb), LAYOUT_CONTENT2_VB_KEY); layout_pane_set_content(radio_vb, layout->content[1]); radio_vb = (GtkWidget *)g_object_get_data(G_OBJECT(main_vb), LAYOUT_CONTENT3_VB_KEY); layout_pane_set_content(radio_vb, layout->content[2]); } static void layout_get(GtkWidget * main_vb, layout_t *layout_out) { GtkWidget *radio_vb; GtkWidget ** layout_type_buttons = (GtkWidget **)g_object_get_data(G_OBJECT(main_vb), LAYOUT_TYPE_BUTTONS_KEY); int i; for (i=0; itype = (layout_type_e)(i + 1); break; } } radio_vb = (GtkWidget *)g_object_get_data(G_OBJECT(main_vb), LAYOUT_CONTENT1_VB_KEY); layout_out->content[0] = layout_pane_get_content(radio_vb); radio_vb = (GtkWidget *)g_object_get_data(G_OBJECT(main_vb), LAYOUT_CONTENT2_VB_KEY); layout_out->content[1] = layout_pane_get_content(radio_vb); radio_vb = (GtkWidget *)g_object_get_data(G_OBJECT(main_vb), LAYOUT_CONTENT3_VB_KEY); layout_out->content[2] = layout_pane_get_content(radio_vb); } static void layout_validate(layout_t *layout, int pane) { switch (pane) { case 1: if(layout->content[1] == layout->content[0]) { layout->content[1] = layout_pane_content_none; } if(layout->content[2] == layout->content[0]) { layout->content[2] = layout_pane_content_none; } break; case 2: if(layout->content[0] == layout->content[1]) { layout->content[0] = layout_pane_content_none; } if(layout->content[2] == layout->content[1]) { layout->content[2] = layout_pane_content_none; } break; case 3: if(layout->content[0] == layout->content[2]) { layout->content[0] = layout_pane_content_none; } if(layout->content[1] == layout->content[2]) { layout->content[1] = layout_pane_content_none; } break; default: /* If the user selects "None" we're not going to intervene. */ break; } } static void layout_validate_cb(GtkWidget *rb, gpointer data) { int pane = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(rb), LAYOUT_PANE_KEY)); layout_t layout; layout_get((GtkWidget *)data, &layout); layout_validate(&layout, pane); layout_set((GtkWidget *)data, &layout); } static void layout_defaults_cb (GtkWidget * w _U_, gpointer data) { layout_t default_layout = { layout_type_5, { layout_pane_content_plist, layout_pane_content_pdetails, layout_pane_content_pbytes } }; layout_set((GtkWidget *)data, &default_layout); } #define ALTERN_COLORS_KEY "altern_colors" #define HEX_DUMP_HIGHLIGHT_STYLE_KEY "hex_dump_highlight_style" #define FILTER_TOOLBAR_PLACEMENT_KEY "filter_toolbar_show_in_statusbar" #define GUI_TOOLBAR_STYLE_KEY "toolbar_style" #define GUI_FILTER_TOOLBAR_STYLE_KEY "filter_toolbar_style" #define GUI_WINDOW_TITLE_KEY "window_title" static const enum_val_t altern_colors_vals[] = { { "FALSE", "No", FALSE }, { "TRUE", "Yes", TRUE }, { NULL, NULL, 0 } }; static const enum_val_t highlight_style_vals[] = { { "FALSE", "Bold", FALSE }, { "TRUE", "Inverse", TRUE }, { NULL, NULL, 0 } }; static const enum_val_t filter_toolbar_placement_vals[] = { { "FALSE", "Below the main toolbar", FALSE }, { "TRUE", "Insert into statusbar", TRUE }, { NULL, NULL, 0 } }; static const enum_val_t toolbar_style_vals[] = { { "ICONS", "Icons only", TB_STYLE_ICONS }, { "TEXT", "Text only", TB_STYLE_TEXT }, { "BOTH", "Icons & Text", TB_STYLE_BOTH }, { NULL, NULL, 0 } }; GtkWidget* layout_prefs_show(void) { GtkWidget *main_vb, *button_hb, *type_tb; GtkWidget *pane_fr, *pane_vb; GtkWidget *radio_hb, *radio_vb; GtkWidget *default_vb, *default_bt; GtkWidget *main_grid, *hbox; GtkWidget *altern_colors_om; GtkWidget *highlight_style_om; GtkWidget *toolbar_style_om; GtkWidget *filter_toolbar_style_om; GtkWidget *filter_toolbar_placement_om; GtkWidget *window_title_te; GtkWidget ** layout_type_buttons = (GtkWidget **)g_malloc (sizeof(GtkWidget*) * LAYOUT_QTY); GtkWidget *layout_pixbufs[LAYOUT_QTY]; int pos = 0; int i; /* main vertical box */ main_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 7, FALSE); gtk_container_set_border_width(GTK_CONTAINER(main_vb), 5); /* pane frame */ pane_fr = gtk_frame_new("Panes"); gtk_box_pack_start(GTK_BOX(main_vb), pane_fr, FALSE, FALSE, 0); gtk_widget_show(pane_fr); /* pane vertical box */ pane_vb = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 7, FALSE); gtk_container_set_border_width(GTK_CONTAINER(pane_vb), 5); gtk_container_add(GTK_CONTAINER(pane_fr), pane_vb); gtk_widget_show(pane_vb); /* button hbox */ button_hb = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0, FALSE); gtk_container_set_border_width(GTK_CONTAINER(button_hb), 6); gtk_box_pack_start (GTK_BOX(pane_vb), button_hb, FALSE, FALSE, 0); /* pane layout */ layout_pixbufs[0] = gtk_image_new_from_pixbuf(gdk_pixbuf_new_from_inline(-1, layout_5_pb_data, FALSE, NULL)); layout_pixbufs[1] = gtk_image_new_from_pixbuf(gdk_pixbuf_new_from_inline(-1, layout_2_pb_data, FALSE, NULL)); layout_pixbufs[2] = gtk_image_new_from_pixbuf(gdk_pixbuf_new_from_inline(-1, layout_1_pb_data, FALSE, NULL)); layout_pixbufs[3] = gtk_image_new_from_pixbuf(gdk_pixbuf_new_from_inline(-1, layout_4_pb_data, FALSE, NULL)); layout_pixbufs[4] = gtk_image_new_from_pixbuf(gdk_pixbuf_new_from_inline(-1, layout_3_pb_data, FALSE, NULL)); layout_pixbufs[5] = gtk_image_new_from_pixbuf(gdk_pixbuf_new_from_inline(-1, layout_6_pb_data, FALSE, NULL)); for (i=0; i