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/resolv.h>*/
35 #include <epan/prefs.h>
36 /*#include "prefs_dlg.h"*/
39 #include "compat_macros.h"
40 #include "dlg_utils.h"
42 #include "../image/icon_layout_1.xpm"
43 #include "../image/icon_layout_2.xpm"
44 #include "../image/icon_layout_3.xpm"
45 #include "../image/icon_layout_4.xpm"
46 #include "../image/icon_layout_5.xpm"
47 #include "../image/icon_layout_6.xpm"
49 #define LAYOUT_QTY (layout_type_max - 1)
52 static void layout_validate_cb(GtkWidget *w _U_, gpointer data);
58 layout_pane_content_e content[3];
62 #define LAYOUT_TYPE_BUTTONS_KEY "layout_type_buttons"
64 #define LAYOUT_NONE_RB_KEY "layout_none_radio_button"
65 #define LAYOUT_PLIST_RB_KEY "layout_plist_radio_button"
66 #define LAYOUT_PDETAILS_RB_KEY "layout_pdetails_radio_button"
67 #define LAYOUT_PBYTES_RB_KEY "layout_pbytes_radio_button"
69 #define LAYOUT_CONTENT1_VB_KEY "layout_content1_vbox"
70 #define LAYOUT_CONTENT2_VB_KEY "layout_content2_vbox"
71 #define LAYOUT_CONTENT3_VB_KEY "layout_content3_vbox"
74 static GtkWidget *layout_content_radio_vbox(GtkWidget *main_vb, GtkTooltips *tooltips, int i, layout_pane_content_e content) {
75 GtkWidget *radio_vb, *radio_lb;
76 GtkWidget *radio_none_rb, *radio_plist_rb, *radio_pdetails_rb, *radio_pbytes_rb;
81 radio_vb = gtk_vbox_new(FALSE, 0);
82 gtk_container_set_border_width(GTK_CONTAINER(radio_vb), 6);
84 g_snprintf (buf, sizeof(buf), "Pane %d:", i);
85 radio_lb = gtk_label_new(buf);
86 gtk_misc_set_alignment(GTK_MISC(radio_lb), 0.0, 0.5);
87 gtk_container_add(GTK_CONTAINER(radio_vb), radio_lb);
89 radio_none_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(NULL, "None", NULL);
90 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(radio_none_rb), content == layout_pane_content_none);
91 gtk_tooltips_set_tip (tooltips, radio_none_rb, "Put nothing in this pane.", NULL);
92 gtk_container_add(GTK_CONTAINER(radio_vb), radio_none_rb);
94 radio_plist_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(radio_none_rb, "Packet List", NULL);
95 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(radio_plist_rb), content == layout_pane_content_plist);
96 gtk_tooltips_set_tip (tooltips, radio_plist_rb, "Put the packet list in this pane.", NULL);
97 gtk_container_add(GTK_CONTAINER(radio_vb), radio_plist_rb);
99 radio_pdetails_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(radio_none_rb, "Packet Details", NULL);
100 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(radio_pdetails_rb), content == layout_pane_content_pdetails);
101 gtk_tooltips_set_tip (tooltips, radio_pdetails_rb, "Put the packet details tree in this pane.", NULL);
102 gtk_container_add(GTK_CONTAINER(radio_vb), radio_pdetails_rb);
104 radio_pbytes_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(radio_none_rb, "Packet Bytes", NULL);
105 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(radio_pbytes_rb), content == layout_pane_content_pbytes);
106 gtk_tooltips_set_tip (tooltips, radio_pbytes_rb, "Put the packet bytes hexdump in this pane.", NULL);
107 gtk_container_add(GTK_CONTAINER(radio_vb), radio_pbytes_rb);
109 OBJECT_SET_DATA(radio_vb, LAYOUT_NONE_RB_KEY, radio_none_rb);
110 OBJECT_SET_DATA(radio_vb, LAYOUT_PLIST_RB_KEY, radio_plist_rb);
111 OBJECT_SET_DATA(radio_vb, LAYOUT_PDETAILS_RB_KEY, radio_pdetails_rb);
112 OBJECT_SET_DATA(radio_vb, LAYOUT_PBYTES_RB_KEY, radio_pbytes_rb);
114 SIGNAL_CONNECT(radio_none_rb, "toggled", layout_validate_cb, main_vb);
115 SIGNAL_CONNECT(radio_plist_rb, "toggled", layout_validate_cb, main_vb);
116 SIGNAL_CONNECT(radio_pdetails_rb, "toggled", layout_validate_cb, main_vb);
117 SIGNAL_CONNECT(radio_pbytes_rb, "toggled", layout_validate_cb, main_vb);
123 layout_type_changed_cb (GtkToggleButton * togglebutton, gpointer user_data)
125 GtkWidget ** layout_type_buttons = (GtkWidget**) user_data;
126 static gboolean dampen_feedback_loop = FALSE;
128 if (!dampen_feedback_loop) {
130 dampen_feedback_loop = TRUE;
131 for (i=0; i<LAYOUT_QTY; ++i) {
132 GtkToggleButton * tb = GTK_TOGGLE_BUTTON(layout_type_buttons[i]);
133 gboolean active = togglebutton==tb;
134 if (gtk_toggle_button_get_active(tb) != active)
135 gtk_toggle_button_set_active (tb, active);
137 dampen_feedback_loop = FALSE;
142 static layout_pane_content_e layout_pane_get_content(GtkWidget * radio_vb) {
144 if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(OBJECT_GET_DATA(radio_vb, LAYOUT_NONE_RB_KEY))))
145 return layout_pane_content_none;
146 if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(OBJECT_GET_DATA(radio_vb, LAYOUT_PLIST_RB_KEY))))
147 return layout_pane_content_plist;
148 if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(OBJECT_GET_DATA(radio_vb, LAYOUT_PDETAILS_RB_KEY))))
149 return layout_pane_content_pdetails;
150 if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(OBJECT_GET_DATA(radio_vb, LAYOUT_PBYTES_RB_KEY))))
151 return layout_pane_content_pbytes;
153 g_assert_not_reached();
157 static void layout_pane_set_content(GtkWidget * radio_vb, layout_pane_content_e pane_content) {
160 switch(pane_content) {
161 case(layout_pane_content_none):
162 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(OBJECT_GET_DATA(radio_vb, LAYOUT_NONE_RB_KEY)), TRUE);
164 case(layout_pane_content_plist):
165 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(OBJECT_GET_DATA(radio_vb, LAYOUT_PLIST_RB_KEY)), TRUE);
167 case(layout_pane_content_pdetails):
168 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(OBJECT_GET_DATA(radio_vb, LAYOUT_PDETAILS_RB_KEY)), TRUE);
170 case(layout_pane_content_pbytes):
171 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(OBJECT_GET_DATA(radio_vb, LAYOUT_PBYTES_RB_KEY)), TRUE);
174 g_assert_not_reached();
180 static void layout_set(GtkWidget * main_vb, layout_t *layout) {
182 GtkWidget ** layout_type_buttons = OBJECT_GET_DATA(main_vb, LAYOUT_TYPE_BUTTONS_KEY);
184 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(layout_type_buttons[layout->type - 1]), TRUE);
186 radio_vb = OBJECT_GET_DATA(main_vb, LAYOUT_CONTENT1_VB_KEY);
187 layout_pane_set_content(radio_vb, layout->content[0]);
188 radio_vb = OBJECT_GET_DATA(main_vb, LAYOUT_CONTENT2_VB_KEY);
189 layout_pane_set_content(radio_vb, layout->content[1]);
190 radio_vb = OBJECT_GET_DATA(main_vb, LAYOUT_CONTENT3_VB_KEY);
191 layout_pane_set_content(radio_vb, layout->content[2]);
194 static void layout_get(GtkWidget * main_vb, layout_t *layout_out) {
196 GtkWidget ** layout_type_buttons = OBJECT_GET_DATA(main_vb, LAYOUT_TYPE_BUTTONS_KEY);
199 for (i=0; i<LAYOUT_QTY; ++i) {
200 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(layout_type_buttons[i]))) {
201 layout_out->type = i + 1;
206 radio_vb = OBJECT_GET_DATA(main_vb, LAYOUT_CONTENT1_VB_KEY);
207 layout_out->content[0] = layout_pane_get_content(radio_vb);
208 radio_vb = OBJECT_GET_DATA(main_vb, LAYOUT_CONTENT2_VB_KEY);
209 layout_out->content[1] = layout_pane_get_content(radio_vb);
210 radio_vb = OBJECT_GET_DATA(main_vb, LAYOUT_CONTENT3_VB_KEY);
211 layout_out->content[2] = layout_pane_get_content(radio_vb);
214 static void layout_validate(layout_t *layout) {
216 if(layout->content[1] == layout->content[0]) {
217 layout->content[1] = layout_pane_content_none;
219 if(layout->content[2] == layout->content[0] || layout->content[2] == layout->content[1]) {
220 layout->content[2] = layout_pane_content_none;
225 static void layout_validate_cb(GtkWidget *w _U_, gpointer data) {
228 layout_get(data, &layout);
229 layout_validate(&layout);
230 layout_set(data, &layout);
234 layout_defaults_cb (GtkWidget * w _U_, gpointer data _U_)
236 layout_t default_layout = {
239 layout_pane_content_plist,
240 layout_pane_content_pdetails,
241 layout_pane_content_pbytes
245 layout_set(data, &default_layout);
250 layout_prefs_show(void)
252 #if GTK_MAJOR_VERSION < 2
253 GtkAccelGroup *accel_group;
255 GtkTooltips *tooltips;
257 GtkWidget *main_vb, *button_hb, *type_tb;
258 GtkWidget *radio_hb, *radio_vb;
259 GtkWidget *default_vb, *default_bt;
261 const char ** inline_txt [LAYOUT_QTY] = {
262 icon_layout_5_xpm, icon_layout_2_xpm, icon_layout_1_xpm,
263 icon_layout_4_xpm, icon_layout_3_xpm, icon_layout_6_xpm };
264 GtkWidget ** layout_type_buttons = g_malloc (sizeof(GtkWidget*) * LAYOUT_QTY);
269 /* main vertical box */
270 main_vb = gtk_vbox_new(FALSE, 7);
271 gtk_container_set_border_width(GTK_CONTAINER(main_vb), 5);
273 #if GTK_MAJOR_VERSION < 2
274 /* Accelerator group for the accelerators (or, as they're called in
275 Windows and, I think, in Motif, "mnemonics"; Alt+<key> is a mnemonic,
276 Ctrl+<key> is an accelerator). */
277 accel_group = gtk_accel_group_new();
278 /*gtk_window_add_accel_group(GTK_WINDOW(main_win), accel_group);*/
281 /* Enable tooltips */
282 tooltips = gtk_tooltips_new();
286 button_hb = gtk_hbox_new(FALSE, 0);
287 gtk_container_set_border_width(GTK_CONTAINER(button_hb), 6);
288 gtk_box_pack_start (GTK_BOX(main_vb), button_hb, FALSE, FALSE, 0);
291 for (i=0; i<LAYOUT_QTY; ++i)
293 type_tb = gtk_toggle_button_new ();
294 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(type_tb),
295 (layout_type_e)(i + 1) == prefs.gui_layout_type);
297 gtk_container_add (GTK_CONTAINER(type_tb), xpm_to_widget(inline_txt[i]));
299 SIGNAL_CONNECT(type_tb, "toggled", layout_type_changed_cb, layout_type_buttons);
300 layout_type_buttons[i] = type_tb;
301 gtk_box_pack_start (GTK_BOX(button_hb), type_tb, TRUE, FALSE, 0);
304 OBJECT_SET_DATA(main_vb, LAYOUT_TYPE_BUTTONS_KEY, layout_type_buttons);
307 radio_hb = gtk_hbox_new(FALSE, 0);
308 gtk_container_set_border_width(GTK_CONTAINER(radio_hb), 6);
309 gtk_box_pack_start (GTK_BOX(main_vb), radio_hb, FALSE, FALSE, 0);
311 radio_vb = layout_content_radio_vbox(main_vb, tooltips, 1, prefs.gui_layout_content_1);
312 gtk_container_set_border_width(GTK_CONTAINER(radio_vb), 6);
313 gtk_box_pack_start (GTK_BOX(radio_hb), radio_vb, FALSE, FALSE, 0);
314 OBJECT_SET_DATA(main_vb, LAYOUT_CONTENT1_VB_KEY, radio_vb);
316 radio_vb = layout_content_radio_vbox(main_vb, tooltips, 2, prefs.gui_layout_content_2);
317 gtk_container_set_border_width(GTK_CONTAINER(radio_vb), 6);
318 gtk_box_pack_start (GTK_BOX(radio_hb), radio_vb, FALSE, FALSE, 0);
319 OBJECT_SET_DATA(main_vb, LAYOUT_CONTENT2_VB_KEY, radio_vb);
321 radio_vb = layout_content_radio_vbox(main_vb, tooltips, 3, prefs.gui_layout_content_3);
322 gtk_container_set_border_width(GTK_CONTAINER(radio_vb), 6);
323 gtk_box_pack_start (GTK_BOX(radio_hb), radio_vb, FALSE, FALSE, 0);
324 OBJECT_SET_DATA(main_vb, LAYOUT_CONTENT3_VB_KEY, radio_vb);
326 default_vb = gtk_vbox_new(FALSE, 0);
327 default_bt = gtk_button_new_with_label("Defaults");
328 gtk_tooltips_set_tip (tooltips, default_bt, "Reset the pane layout settings to default values.", NULL);
329 SIGNAL_CONNECT(default_bt, "clicked", layout_defaults_cb, main_vb);
330 gtk_box_pack_end(GTK_BOX(default_vb), default_bt, FALSE, FALSE, 0);
331 gtk_box_pack_end(GTK_BOX(radio_hb), default_vb, FALSE, FALSE, 0);
333 /* Show 'em what we got */
334 gtk_widget_show_all(main_vb);
340 layout_prefs_fetch(GtkWidget *w)
342 layout_t layout_fetched;
344 layout_get(w, &layout_fetched);
346 prefs.gui_layout_type = layout_fetched.type;
347 prefs.gui_layout_content_1 = layout_fetched.content[0];
348 prefs.gui_layout_content_2 = layout_fetched.content[1];
349 prefs.gui_layout_content_3 = layout_fetched.content[2];
353 layout_prefs_apply(GtkWidget *w _U_)
355 main_widgets_rearrange();
359 layout_prefs_destroy(GtkWidget *main_vb)
361 GtkWidget ** layout_type_buttons = OBJECT_GET_DATA(main_vb, LAYOUT_TYPE_BUTTONS_KEY);
363 g_free(layout_type_buttons);