2 * Dialog box for layout preferences
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.
32 #include "layout_prefs.h"
33 #include "gtkglobals.h"
34 #include <epan/prefs.h>
35 #include "gui_utils.h"
37 #include "compat_macros.h"
38 #include "dlg_utils.h"
40 #include "../image/icon_layout_1.xpm"
41 #include "../image/icon_layout_2.xpm"
42 #include "../image/icon_layout_3.xpm"
43 #include "../image/icon_layout_4.xpm"
44 #include "../image/icon_layout_5.xpm"
45 #include "../image/icon_layout_6.xpm"
47 #define LAYOUT_QTY (layout_type_max - 1)
50 static void layout_validate_cb(GtkWidget *w _U_, gpointer data);
56 layout_pane_content_e content[3];
60 #define LAYOUT_TYPE_BUTTONS_KEY "layout_type_buttons"
62 #define LAYOUT_NONE_RB_KEY "layout_none_radio_button"
63 #define LAYOUT_PLIST_RB_KEY "layout_plist_radio_button"
64 #define LAYOUT_PDETAILS_RB_KEY "layout_pdetails_radio_button"
65 #define LAYOUT_PBYTES_RB_KEY "layout_pbytes_radio_button"
67 #define LAYOUT_CONTENT1_VB_KEY "layout_content1_vbox"
68 #define LAYOUT_CONTENT2_VB_KEY "layout_content2_vbox"
69 #define LAYOUT_CONTENT3_VB_KEY "layout_content3_vbox"
72 static GtkWidget *layout_content_radio_vbox(GtkWidget *main_vb, GtkTooltips *tooltips, int i, layout_pane_content_e content) {
73 GtkWidget *radio_vb, *radio_lb;
74 GtkWidget *radio_none_rb, *radio_plist_rb, *radio_pdetails_rb, *radio_pbytes_rb;
79 radio_vb = gtk_vbox_new(FALSE, 0);
80 gtk_container_set_border_width(GTK_CONTAINER(radio_vb), 6);
82 g_snprintf (buf, sizeof(buf), "Pane %d:", i);
83 radio_lb = gtk_label_new(buf);
84 gtk_misc_set_alignment(GTK_MISC(radio_lb), 0.0, 0.5);
85 gtk_container_add(GTK_CONTAINER(radio_vb), radio_lb);
87 radio_none_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(NULL, "None", NULL);
88 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(radio_none_rb), content == layout_pane_content_none);
89 gtk_tooltips_set_tip (tooltips, radio_none_rb, "Put nothing in this pane.", NULL);
90 gtk_container_add(GTK_CONTAINER(radio_vb), radio_none_rb);
92 radio_plist_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(radio_none_rb, "Packet List", NULL);
93 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(radio_plist_rb), content == layout_pane_content_plist);
94 gtk_tooltips_set_tip (tooltips, radio_plist_rb, "Put the packet list in this pane.", NULL);
95 gtk_container_add(GTK_CONTAINER(radio_vb), radio_plist_rb);
97 radio_pdetails_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(radio_none_rb, "Packet Details", NULL);
98 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(radio_pdetails_rb), content == layout_pane_content_pdetails);
99 gtk_tooltips_set_tip (tooltips, radio_pdetails_rb, "Put the packet details tree in this pane.", NULL);
100 gtk_container_add(GTK_CONTAINER(radio_vb), radio_pdetails_rb);
102 radio_pbytes_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(radio_none_rb, "Packet Bytes", NULL);
103 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(radio_pbytes_rb), content == layout_pane_content_pbytes);
104 gtk_tooltips_set_tip (tooltips, radio_pbytes_rb, "Put the packet bytes hexdump in this pane.", NULL);
105 gtk_container_add(GTK_CONTAINER(radio_vb), radio_pbytes_rb);
107 OBJECT_SET_DATA(radio_vb, LAYOUT_NONE_RB_KEY, radio_none_rb);
108 OBJECT_SET_DATA(radio_vb, LAYOUT_PLIST_RB_KEY, radio_plist_rb);
109 OBJECT_SET_DATA(radio_vb, LAYOUT_PDETAILS_RB_KEY, radio_pdetails_rb);
110 OBJECT_SET_DATA(radio_vb, LAYOUT_PBYTES_RB_KEY, radio_pbytes_rb);
112 SIGNAL_CONNECT(radio_none_rb, "toggled", layout_validate_cb, main_vb);
113 SIGNAL_CONNECT(radio_plist_rb, "toggled", layout_validate_cb, main_vb);
114 SIGNAL_CONNECT(radio_pdetails_rb, "toggled", layout_validate_cb, main_vb);
115 SIGNAL_CONNECT(radio_pbytes_rb, "toggled", layout_validate_cb, main_vb);
121 layout_type_changed_cb (GtkToggleButton * togglebutton, gpointer user_data)
123 GtkWidget ** layout_type_buttons = (GtkWidget**) user_data;
124 static gboolean dampen_feedback_loop = FALSE;
126 if (!dampen_feedback_loop) {
128 dampen_feedback_loop = TRUE;
129 for (i=0; i<LAYOUT_QTY; ++i) {
130 GtkToggleButton * tb = GTK_TOGGLE_BUTTON(layout_type_buttons[i]);
131 gboolean active = togglebutton==tb;
132 if (gtk_toggle_button_get_active(tb) != active)
133 gtk_toggle_button_set_active (tb, active);
135 dampen_feedback_loop = FALSE;
140 static layout_pane_content_e layout_pane_get_content(GtkWidget * radio_vb) {
142 if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(OBJECT_GET_DATA(radio_vb, LAYOUT_NONE_RB_KEY))))
143 return layout_pane_content_none;
144 if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(OBJECT_GET_DATA(radio_vb, LAYOUT_PLIST_RB_KEY))))
145 return layout_pane_content_plist;
146 if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(OBJECT_GET_DATA(radio_vb, LAYOUT_PDETAILS_RB_KEY))))
147 return layout_pane_content_pdetails;
148 if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(OBJECT_GET_DATA(radio_vb, LAYOUT_PBYTES_RB_KEY))))
149 return layout_pane_content_pbytes;
151 g_assert_not_reached();
155 static void layout_pane_set_content(GtkWidget * radio_vb, layout_pane_content_e pane_content) {
158 switch(pane_content) {
159 case(layout_pane_content_none):
160 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(OBJECT_GET_DATA(radio_vb, LAYOUT_NONE_RB_KEY)), TRUE);
162 case(layout_pane_content_plist):
163 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(OBJECT_GET_DATA(radio_vb, LAYOUT_PLIST_RB_KEY)), TRUE);
165 case(layout_pane_content_pdetails):
166 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(OBJECT_GET_DATA(radio_vb, LAYOUT_PDETAILS_RB_KEY)), TRUE);
168 case(layout_pane_content_pbytes):
169 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(OBJECT_GET_DATA(radio_vb, LAYOUT_PBYTES_RB_KEY)), TRUE);
172 g_assert_not_reached();
178 static void layout_set(GtkWidget * main_vb, layout_t *layout) {
180 GtkWidget ** layout_type_buttons = OBJECT_GET_DATA(main_vb, LAYOUT_TYPE_BUTTONS_KEY);
182 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(layout_type_buttons[layout->type - 1]), TRUE);
184 radio_vb = OBJECT_GET_DATA(main_vb, LAYOUT_CONTENT1_VB_KEY);
185 layout_pane_set_content(radio_vb, layout->content[0]);
186 radio_vb = OBJECT_GET_DATA(main_vb, LAYOUT_CONTENT2_VB_KEY);
187 layout_pane_set_content(radio_vb, layout->content[1]);
188 radio_vb = OBJECT_GET_DATA(main_vb, LAYOUT_CONTENT3_VB_KEY);
189 layout_pane_set_content(radio_vb, layout->content[2]);
192 static void layout_get(GtkWidget * main_vb, layout_t *layout_out) {
194 GtkWidget ** layout_type_buttons = OBJECT_GET_DATA(main_vb, LAYOUT_TYPE_BUTTONS_KEY);
197 for (i=0; i<LAYOUT_QTY; ++i) {
198 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(layout_type_buttons[i]))) {
199 layout_out->type = i + 1;
204 radio_vb = OBJECT_GET_DATA(main_vb, LAYOUT_CONTENT1_VB_KEY);
205 layout_out->content[0] = layout_pane_get_content(radio_vb);
206 radio_vb = OBJECT_GET_DATA(main_vb, LAYOUT_CONTENT2_VB_KEY);
207 layout_out->content[1] = layout_pane_get_content(radio_vb);
208 radio_vb = OBJECT_GET_DATA(main_vb, LAYOUT_CONTENT3_VB_KEY);
209 layout_out->content[2] = layout_pane_get_content(radio_vb);
212 static void layout_validate(layout_t *layout) {
214 if(layout->content[1] == layout->content[0]) {
215 layout->content[1] = layout_pane_content_none;
217 if(layout->content[2] == layout->content[0] || layout->content[2] == layout->content[1]) {
218 layout->content[2] = layout_pane_content_none;
223 static void layout_validate_cb(GtkWidget *w _U_, gpointer data) {
226 layout_get(data, &layout);
227 layout_validate(&layout);
228 layout_set(data, &layout);
232 layout_defaults_cb (GtkWidget * w _U_, gpointer data _U_)
234 layout_t default_layout = {
237 layout_pane_content_plist,
238 layout_pane_content_pdetails,
239 layout_pane_content_pbytes
243 layout_set(data, &default_layout);
248 layout_prefs_show(void)
250 #if GTK_MAJOR_VERSION < 2
251 GtkAccelGroup *accel_group;
253 GtkTooltips *tooltips;
255 GtkWidget *main_vb, *button_hb, *type_tb;
256 GtkWidget *radio_hb, *radio_vb;
257 GtkWidget *default_vb, *default_bt;
259 const char ** inline_txt [LAYOUT_QTY] = {
260 icon_layout_5_xpm, icon_layout_2_xpm, icon_layout_1_xpm,
261 icon_layout_4_xpm, icon_layout_3_xpm, icon_layout_6_xpm };
262 GtkWidget ** layout_type_buttons = g_malloc (sizeof(GtkWidget*) * LAYOUT_QTY);
267 /* main vertical box */
268 main_vb = gtk_vbox_new(FALSE, 7);
269 gtk_container_set_border_width(GTK_CONTAINER(main_vb), 5);
271 #if GTK_MAJOR_VERSION < 2
272 /* Accelerator group for the accelerators (or, as they're called in
273 Windows and, I think, in Motif, "mnemonics"; Alt+<key> is a mnemonic,
274 Ctrl+<key> is an accelerator). */
275 accel_group = gtk_accel_group_new();
276 /*gtk_window_add_accel_group(GTK_WINDOW(main_win), accel_group);*/
279 /* Enable tooltips */
280 tooltips = gtk_tooltips_new();
284 button_hb = gtk_hbox_new(FALSE, 0);
285 gtk_container_set_border_width(GTK_CONTAINER(button_hb), 6);
286 gtk_box_pack_start (GTK_BOX(main_vb), button_hb, FALSE, FALSE, 0);
289 for (i=0; i<LAYOUT_QTY; ++i)
291 type_tb = gtk_toggle_button_new ();
292 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(type_tb),
293 (layout_type_e)(i + 1) == prefs.gui_layout_type);
295 gtk_container_add (GTK_CONTAINER(type_tb), xpm_to_widget(inline_txt[i]));
297 SIGNAL_CONNECT(type_tb, "toggled", layout_type_changed_cb, layout_type_buttons);
298 layout_type_buttons[i] = type_tb;
299 gtk_box_pack_start (GTK_BOX(button_hb), type_tb, TRUE, FALSE, 0);
302 OBJECT_SET_DATA(main_vb, LAYOUT_TYPE_BUTTONS_KEY, layout_type_buttons);
305 radio_hb = gtk_hbox_new(FALSE, 0);
306 gtk_container_set_border_width(GTK_CONTAINER(radio_hb), 6);
307 gtk_box_pack_start (GTK_BOX(main_vb), radio_hb, FALSE, FALSE, 0);
309 radio_vb = layout_content_radio_vbox(main_vb, tooltips, 1, prefs.gui_layout_content_1);
310 gtk_container_set_border_width(GTK_CONTAINER(radio_vb), 6);
311 gtk_box_pack_start (GTK_BOX(radio_hb), radio_vb, FALSE, FALSE, 0);
312 OBJECT_SET_DATA(main_vb, LAYOUT_CONTENT1_VB_KEY, radio_vb);
314 radio_vb = layout_content_radio_vbox(main_vb, tooltips, 2, prefs.gui_layout_content_2);
315 gtk_container_set_border_width(GTK_CONTAINER(radio_vb), 6);
316 gtk_box_pack_start (GTK_BOX(radio_hb), radio_vb, FALSE, FALSE, 0);
317 OBJECT_SET_DATA(main_vb, LAYOUT_CONTENT2_VB_KEY, radio_vb);
319 radio_vb = layout_content_radio_vbox(main_vb, tooltips, 3, prefs.gui_layout_content_3);
320 gtk_container_set_border_width(GTK_CONTAINER(radio_vb), 6);
321 gtk_box_pack_start (GTK_BOX(radio_hb), radio_vb, FALSE, FALSE, 0);
322 OBJECT_SET_DATA(main_vb, LAYOUT_CONTENT3_VB_KEY, radio_vb);
324 default_vb = gtk_vbox_new(FALSE, 0);
325 default_bt = gtk_button_new_with_label("Defaults");
326 gtk_tooltips_set_tip (tooltips, default_bt, "Reset the pane layout settings to default values.", NULL);
327 SIGNAL_CONNECT(default_bt, "clicked", layout_defaults_cb, main_vb);
328 gtk_box_pack_end(GTK_BOX(default_vb), default_bt, FALSE, FALSE, 0);
329 gtk_box_pack_end(GTK_BOX(radio_hb), default_vb, FALSE, FALSE, 0);
331 /* Show 'em what we got */
332 gtk_widget_show_all(main_vb);
338 layout_prefs_fetch(GtkWidget *w)
340 layout_t layout_fetched;
342 layout_get(w, &layout_fetched);
344 prefs.gui_layout_type = layout_fetched.type;
345 prefs.gui_layout_content_1 = layout_fetched.content[0];
346 prefs.gui_layout_content_2 = layout_fetched.content[1];
347 prefs.gui_layout_content_3 = layout_fetched.content[2];
351 layout_prefs_apply(GtkWidget *w _U_)
353 main_widgets_rearrange();
357 layout_prefs_destroy(GtkWidget *main_vb)
359 GtkWidget ** layout_type_buttons = OBJECT_GET_DATA(main_vb, LAYOUT_TYPE_BUTTONS_KEY);
361 g_free(layout_type_buttons);