/* layout_prefs.c * Dialog box for layout preferences * * $Id$ * * Ethereal - 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. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "globals.h" #include "layout_prefs.h" #include "gtkglobals.h" #include #include "prefs_dlg.h" #include "gui_utils.h" #include "main.h" #include "compat_macros.h" #include "dlg_utils.h" #include "../ui_util.h" #include "../image/icon_layout_1.xpm" #include "../image/icon_layout_2.xpm" #include "../image/icon_layout_3.xpm" #include "../image/icon_layout_4.xpm" #include "../image/icon_layout_5.xpm" #include "../image/icon_layout_6.xpm" #define LAYOUT_QTY (layout_type_max - 1) static void layout_validate_cb(GtkWidget *w _U_, 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" static GtkWidget *layout_content_radio_vbox(GtkWidget *main_vb, GtkTooltips *tooltips, 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 = gtk_vbox_new(FALSE, 0); 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.0, 0.5); gtk_container_add(GTK_CONTAINER(radio_vb), radio_lb); radio_none_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(NULL, "None", NULL); gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(radio_none_rb), content == layout_pane_content_none); gtk_tooltips_set_tip (tooltips, radio_none_rb, "Put nothing in this pane.", NULL); gtk_container_add(GTK_CONTAINER(radio_vb), radio_none_rb); radio_plist_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(radio_none_rb, "Packet List", NULL); gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(radio_plist_rb), content == layout_pane_content_plist); gtk_tooltips_set_tip (tooltips, radio_plist_rb, "Put the packet list in this pane.", NULL); gtk_container_add(GTK_CONTAINER(radio_vb), radio_plist_rb); radio_pdetails_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(radio_none_rb, "Packet Details", NULL); gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(radio_pdetails_rb), content == layout_pane_content_pdetails); gtk_tooltips_set_tip (tooltips, radio_pdetails_rb, "Put the packet details tree in this pane.", NULL); gtk_container_add(GTK_CONTAINER(radio_vb), radio_pdetails_rb); radio_pbytes_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(radio_none_rb, "Packet Bytes", NULL); gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(radio_pbytes_rb), content == layout_pane_content_pbytes); gtk_tooltips_set_tip (tooltips, radio_pbytes_rb, "Put the packet bytes hexdump in this pane.", NULL); gtk_container_add(GTK_CONTAINER(radio_vb), radio_pbytes_rb); OBJECT_SET_DATA(radio_vb, LAYOUT_NONE_RB_KEY, radio_none_rb); OBJECT_SET_DATA(radio_vb, LAYOUT_PLIST_RB_KEY, radio_plist_rb); OBJECT_SET_DATA(radio_vb, LAYOUT_PDETAILS_RB_KEY, radio_pdetails_rb); OBJECT_SET_DATA(radio_vb, LAYOUT_PBYTES_RB_KEY, radio_pbytes_rb); SIGNAL_CONNECT(radio_none_rb, "toggled", layout_validate_cb, main_vb); SIGNAL_CONNECT(radio_plist_rb, "toggled", layout_validate_cb, main_vb); SIGNAL_CONNECT(radio_pdetails_rb, "toggled", layout_validate_cb, main_vb); SIGNAL_CONNECT(radio_pbytes_rb, "toggled", 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 = OBJECT_GET_DATA(main_vb, LAYOUT_CONTENT1_VB_KEY); layout_pane_set_content(radio_vb, layout->content[0]); radio_vb = OBJECT_GET_DATA(main_vb, LAYOUT_CONTENT2_VB_KEY); layout_pane_set_content(radio_vb, layout->content[1]); radio_vb = OBJECT_GET_DATA(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 = OBJECT_GET_DATA(main_vb, LAYOUT_TYPE_BUTTONS_KEY); int i; for (i=0; itype = i + 1; break; } } radio_vb = OBJECT_GET_DATA(main_vb, LAYOUT_CONTENT1_VB_KEY); layout_out->content[0] = layout_pane_get_content(radio_vb); radio_vb = OBJECT_GET_DATA(main_vb, LAYOUT_CONTENT2_VB_KEY); layout_out->content[1] = layout_pane_get_content(radio_vb); radio_vb = OBJECT_GET_DATA(main_vb, LAYOUT_CONTENT3_VB_KEY); layout_out->content[2] = layout_pane_get_content(radio_vb); } static void layout_validate(layout_t *layout) { 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->content[1]) { layout->content[2] = layout_pane_content_none; } } static void layout_validate_cb(GtkWidget *w _U_, gpointer data) { layout_t layout; layout_get(data, &layout); layout_validate(&layout); layout_set(data, &layout); } static void layout_defaults_cb (GtkWidget * w _U_, gpointer data _U_) { layout_t default_layout = { layout_type_5, { layout_pane_content_plist, layout_pane_content_pdetails, layout_pane_content_pbytes } }; layout_set(data, &default_layout); } #define SCROLLBAR_PLACEMENT_KEY "scrollbar_placement" #if GTK_MAJOR_VERSION < 2 #define PTREE_LINE_STYLE_KEY "ptree_line_style" #define PTREE_EXPANDER_STYLE_KEY "ptree_expander_style" #else #define ALTERN_COLORS_KEY "altern_colors" #endif #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_WINDOW_TITLE_KEY "window_title" #if GTK_MAJOR_VERSION < 2 #define GUI_TABLE_ROWS 6 #else #define GUI_TABLE_ROWS 5 #endif static const enum_val_t scrollbar_placement_vals[] = { { "FALSE", "Left", FALSE }, { "TRUE", "Right", TRUE }, { NULL, NULL, 0 } }; #if GTK_MAJOR_VERSION < 2 static const enum_val_t line_style_vals[] = { { "NONE", "None", 0 }, { "SOLID", "Solid", 1 }, { "DOTTED", "Dotted", 2 }, { "TABBED", "Tabbed", 3 }, { NULL, NULL, 0 } }; static const enum_val_t expander_style_vals[] = { { "NONE", "None", 0 }, { "SQUARE", "Square", 1 }, { "TRIANGLE", "Triangle", 2 }, { "CIRCULAR", "Circular", 3 }, { NULL, NULL, 0 } }; #else static const enum_val_t altern_colors_vals[] = { { "FALSE", "No", FALSE }, { "TRUE", "Yes", TRUE }, { NULL, NULL, 0 } }; #endif 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) { #if GTK_MAJOR_VERSION < 2 GtkAccelGroup *accel_group; #endif GtkWidget *main_vb, *button_hb, *type_tb; GtkWidget *pane_fr, *pane_vb; GtkWidget *radio_hb, *radio_vb; GtkWidget *default_vb, *default_bt; GtkWidget *main_tb, *hbox; GtkWidget *scrollbar_om; #if GTK_MAJOR_VERSION < 2 GtkWidget *expander_style_om, *line_style_om; #else GtkWidget *altern_colors_om; #endif GtkWidget *highlight_style_om; GtkWidget *toolbar_style_om; GtkWidget *filter_toolbar_placement_om; GtkWidget *window_title_te; GtkTooltips *tooltips = gtk_tooltips_new(); const char ** inline_txt [LAYOUT_QTY] = { icon_layout_5_xpm, icon_layout_2_xpm, icon_layout_1_xpm, icon_layout_4_xpm, icon_layout_3_xpm, icon_layout_6_xpm }; GtkWidget ** layout_type_buttons = g_malloc (sizeof(GtkWidget*) * LAYOUT_QTY); int pos = 0; int i; /* main vertical box */ main_vb = gtk_vbox_new(FALSE, 7); gtk_container_set_border_width(GTK_CONTAINER(main_vb), 5); #if GTK_MAJOR_VERSION < 2 /* Accelerator group for the accelerators (or, as they're called in Windows and, I think, in Motif, "mnemonics"; Alt+ is a mnemonic, Ctrl+ is an accelerator). */ accel_group = gtk_accel_group_new(); /*gtk_window_add_accel_group(GTK_WINDOW(main_win), accel_group);*/ #endif /* 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 = gtk_vbox_new(FALSE, 7); 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 = gtk_hbox_new(FALSE, 0); 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 */ for (i=0; i