2 * Routines for handling preferences
4 * $Id: prefs_dlg.c,v 1.25 2001/08/21 06:39:18 guy Exp $
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.
29 #ifdef HAVE_SYS_TYPES_H
30 #include <sys/types.h>
44 #ifdef HAVE_SYS_STAT_H
52 #include "column_prefs.h"
54 #include "prefs_dlg.h"
55 #include "print_prefs.h"
56 #include "stream_prefs.h"
57 #include "gui_prefs.h"
59 #include "dlg_utils.h"
60 #include "simple_dialog.h"
62 #include "prefs-int.h"
64 static void prefs_main_ok_cb(GtkWidget *, gpointer);
65 static void prefs_main_apply_cb(GtkWidget *, gpointer);
66 static void prefs_main_save_cb(GtkWidget *, gpointer);
67 static void prefs_main_cancel_cb(GtkWidget *, gpointer);
68 static gboolean prefs_main_delete_cb(GtkWidget *, gpointer);
69 static void prefs_main_destroy_cb(GtkWidget *, gpointer);
71 #define E_PRINT_PAGE_KEY "printer_options_page"
72 #define E_COLUMN_PAGE_KEY "column_options_page"
73 #define E_STREAM_PAGE_KEY "tcp_stream_options_page"
74 #define E_GUI_PAGE_KEY "gui_options_page"
76 #define FIRST_PROTO_PREFS_PAGE 4
79 * Keep a static pointer to the notebook to be able to choose the
82 static GtkWidget *notebook;
85 * Keep a static pointer to the current "Preferences" window, if any, so that
86 * if somebody tries to do "Edit:Preferences" while there's already a
87 * "Preferences" window up, we just pop up the existing one, rather than
90 static GtkWidget *prefs_w;
93 * Save the value of the preferences as of when the preferences dialog
94 * box was first popped up, so we can revert to those values if the
95 * user selects "Cancel".
97 static e_prefs saved_prefs;
100 pref_show(pref_t *pref, gpointer user_data)
102 GtkWidget *main_tb = user_data;
105 GtkWidget *label, *menu, *menu_item, *widget, *button;
108 const enum_val_t *enum_valp;
109 int menu_index, index;
111 /* Give this preference a label which is its title, followed by a colon,
112 and left-align it. */
114 label_string = g_malloc(strlen(title) + 2);
115 strcpy(label_string, title);
116 strcat(label_string, ":");
117 label = gtk_label_new(label_string);
118 g_free(label_string);
119 gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
121 /* Attach it to the table. */
122 gtk_table_attach_defaults(GTK_TABLE(main_tb), label, 0, 1, pref->ordinal,
125 /* Save the current value of the preference, so that we can revert it if
126 the user does "Apply" and then "Cancel", and create the control for
127 editing the preference. */
128 switch (pref->type) {
131 pref->saved_val.uint = *pref->varp.uint;
133 /* XXX - there are no uint spinbuttons, so we can't use a spinbutton.
134 Even more annoyingly, even if there were, GLib doesn't define
135 G_MAXUINT - but I think ANSI C may define UINT_MAX, so we could
137 widget = gtk_entry_new();
138 switch (pref->info.base) {
141 sprintf(uint_str, "%u", pref->saved_val.uint);
145 sprintf(uint_str, "%o", pref->saved_val.uint);
149 sprintf(uint_str, "%x", pref->saved_val.uint);
152 gtk_entry_set_text(GTK_ENTRY(widget), uint_str);
153 pref->control = widget;
157 pref->saved_val.bool = *pref->varp.bool;
158 widget = gtk_check_button_new();
159 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(widget), pref->saved_val.bool);
160 pref->control = widget;
164 pref->saved_val.enumval = *pref->varp.enump;
165 if (pref->info.enum_info.radio_buttons) {
166 /* Show it as radio buttons. */
167 widget = gtk_hbox_new(FALSE, 0);
169 for (enum_valp = pref->info.enum_info.enumvals, index = 0;
170 enum_valp->name != NULL; enum_valp++, index++) {
171 button = gtk_radio_button_new_with_label(rb_group, enum_valp->name);
172 if (rb_group == NULL)
173 rb_group = gtk_radio_button_group(GTK_RADIO_BUTTON(button));
174 gtk_box_pack_start(GTK_BOX(widget), button, FALSE, FALSE, 10);
175 if (enum_valp->value == pref->saved_val.enumval)
176 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), TRUE);
177 pref->control = button;
180 /* Show it as an option menu. */
181 menu = gtk_menu_new();
183 for (enum_valp = pref->info.enum_info.enumvals, index = 0;
184 enum_valp->name != NULL; enum_valp++, index++) {
185 menu_item = gtk_menu_item_new_with_label(enum_valp->name);
186 gtk_menu_append(GTK_MENU(menu), menu_item);
187 if (enum_valp->value == pref->saved_val.enumval)
189 gtk_widget_show(menu_item);
192 /* Create the option menu from the option */
193 widget = gtk_option_menu_new();
194 gtk_option_menu_set_menu(GTK_OPTION_MENU(widget), menu);
196 /* Set its current value to the variable's current value */
197 if (menu_index != -1)
198 gtk_option_menu_set_history(GTK_OPTION_MENU(widget), menu_index);
199 pref->control = widget;
204 widget = gtk_entry_new();
205 if (pref->saved_val.string != NULL)
206 g_free(pref->saved_val.string);
207 pref->saved_val.string = g_strdup(*pref->varp.string);
208 gtk_entry_set_text(GTK_ENTRY(widget), pref->saved_val.string);
209 pref->control = widget;
213 g_assert_not_reached();
218 gtk_table_attach_defaults(GTK_TABLE(main_tb), widget, 1, 2, pref->ordinal,
223 module_prefs_show(module_t *module, gpointer user_data)
225 GtkWidget *prefs_nb = user_data;
226 GtkWidget *main_vb, *main_tb, *label;
228 /* Main vertical box */
229 main_vb = gtk_vbox_new(FALSE, 5);
230 gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
233 main_tb = gtk_table_new(module->numprefs, 2, FALSE);
234 gtk_box_pack_start(GTK_BOX(main_vb), main_tb, FALSE, FALSE, 0);
235 gtk_table_set_row_spacings(GTK_TABLE(main_tb), 10);
236 gtk_table_set_col_spacings(GTK_TABLE(main_tb), 15);
238 /* Add items for each of the preferences */
239 prefs_pref_foreach(module, pref_show, main_tb);
241 label = gtk_label_new(module->title);
242 gtk_notebook_append_page(GTK_NOTEBOOK(prefs_nb), main_vb, label);
244 /* Show 'em what we got */
245 gtk_widget_show_all(main_vb);
249 prefs_cb(GtkWidget *w, gpointer dummy) {
250 GtkWidget *main_vb, *top_hb, *bbox, *prefs_nb,
251 *ok_bt, *apply_bt, *save_bt, *cancel_bt;
252 GtkWidget *print_pg, *column_pg, *stream_pg, *gui_pg, *label;
254 if (prefs_w != NULL) {
255 /* There's already a "Preferences" dialog box; reactivate it. */
256 reactivate_window(prefs_w);
260 /* Save the current preferences, so we can revert to those values
261 if the user presses "Cancel". */
262 copy_prefs(&saved_prefs, &prefs);
264 prefs_w = dlg_window_new("Ethereal: Preferences");
265 gtk_signal_connect(GTK_OBJECT(prefs_w), "delete_event",
266 GTK_SIGNAL_FUNC(prefs_main_delete_cb), NULL);
267 gtk_signal_connect(GTK_OBJECT(prefs_w), "destroy",
268 GTK_SIGNAL_FUNC(prefs_main_destroy_cb), NULL);
270 /* Container for each row of widgets */
271 main_vb = gtk_vbox_new(FALSE, 5);
272 gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
273 gtk_container_add(GTK_CONTAINER(prefs_w), main_vb);
274 gtk_widget_show(main_vb);
276 /* Top row: Preferences notebook */
277 top_hb = gtk_hbox_new(FALSE, 1);
278 gtk_container_add(GTK_CONTAINER(main_vb), top_hb);
279 gtk_widget_show(top_hb);
281 notebook = prefs_nb = gtk_notebook_new();
282 gtk_container_add(GTK_CONTAINER(main_vb), prefs_nb);
283 gtk_widget_show(prefs_nb);
286 print_pg = printer_prefs_show();
287 gtk_object_set_data(GTK_OBJECT(prefs_w), E_PRINT_PAGE_KEY, print_pg);
288 label = gtk_label_new ("Printing");
289 gtk_notebook_append_page (GTK_NOTEBOOK(prefs_nb), print_pg, label);
292 column_pg = column_prefs_show();
293 gtk_object_set_data(GTK_OBJECT(prefs_w), E_COLUMN_PAGE_KEY, column_pg);
294 label = gtk_label_new ("Columns");
295 gtk_notebook_append_page (GTK_NOTEBOOK(prefs_nb), column_pg, label);
297 /* TCP Streams prefs */
298 stream_pg = stream_prefs_show();
299 gtk_object_set_data(GTK_OBJECT(prefs_w), E_STREAM_PAGE_KEY, stream_pg);
300 label = gtk_label_new ("TCP Streams");
301 gtk_notebook_append_page (GTK_NOTEBOOK(prefs_nb), stream_pg, label);
304 gui_pg = gui_prefs_show();
305 gtk_object_set_data(GTK_OBJECT(prefs_w), E_GUI_PAGE_KEY, gui_pg);
306 label = gtk_label_new ("GUI");
307 gtk_notebook_append_page (GTK_NOTEBOOK(prefs_nb), gui_pg, label);
309 /* Registered prefs */
310 prefs_module_foreach(module_prefs_show, prefs_nb);
312 /* Button row: OK and cancel buttons */
313 bbox = gtk_hbutton_box_new();
314 gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
315 gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
316 gtk_container_add(GTK_CONTAINER(main_vb), bbox);
317 gtk_widget_show(bbox);
319 ok_bt = gtk_button_new_with_label ("OK");
320 gtk_signal_connect(GTK_OBJECT(ok_bt), "clicked",
321 GTK_SIGNAL_FUNC(prefs_main_ok_cb), GTK_OBJECT(prefs_w));
322 GTK_WIDGET_SET_FLAGS(ok_bt, GTK_CAN_DEFAULT);
323 gtk_box_pack_start (GTK_BOX (bbox), ok_bt, TRUE, TRUE, 0);
324 gtk_widget_grab_default(ok_bt);
325 gtk_widget_show(ok_bt);
327 apply_bt = gtk_button_new_with_label ("Apply");
328 gtk_signal_connect(GTK_OBJECT(apply_bt), "clicked",
329 GTK_SIGNAL_FUNC(prefs_main_apply_cb), GTK_OBJECT(prefs_w));
330 GTK_WIDGET_SET_FLAGS(apply_bt, GTK_CAN_DEFAULT);
331 gtk_box_pack_start(GTK_BOX (bbox), apply_bt, TRUE, TRUE, 0);
332 gtk_widget_show(apply_bt);
334 save_bt = gtk_button_new_with_label ("Save");
335 gtk_signal_connect(GTK_OBJECT(save_bt), "clicked",
336 GTK_SIGNAL_FUNC(prefs_main_save_cb), GTK_OBJECT(prefs_w));
337 GTK_WIDGET_SET_FLAGS(save_bt, GTK_CAN_DEFAULT);
338 gtk_box_pack_start (GTK_BOX (bbox), save_bt, TRUE, TRUE, 0);
339 gtk_widget_show(save_bt);
341 cancel_bt = gtk_button_new_with_label ("Cancel");
342 gtk_signal_connect(GTK_OBJECT(cancel_bt), "clicked",
343 GTK_SIGNAL_FUNC(prefs_main_cancel_cb), GTK_OBJECT(prefs_w));
344 GTK_WIDGET_SET_FLAGS(cancel_bt, GTK_CAN_DEFAULT);
345 gtk_box_pack_start (GTK_BOX (bbox), cancel_bt, TRUE, TRUE, 0);
346 gtk_widget_show(cancel_bt);
348 /* Catch the "key_press_event" signal in the window, so that we can catch
349 the ESC key being pressed and act as if the "Cancel" button had
351 dlg_set_cancel(prefs_w, cancel_bt);
353 gtk_widget_show(prefs_w);
357 pref_fetch(pref_t *pref, gpointer user_data)
368 gboolean *pref_changed_p = user_data;
370 /* Fetch the value of the preference, and set the appropriate variable
372 switch (pref->type) {
375 str_val = gtk_entry_get_text(GTK_ENTRY(pref->control));
376 uval = strtoul(str_val, &p, pref->info.base);
378 if (p == value || *p != '\0')
379 return PREFS_SET_SYNTAX_ERR; /* number was bad */
381 if (*pref->varp.uint != uval) {
382 *pref_changed_p = TRUE;
383 *pref->varp.uint = uval;
388 bval = GTK_TOGGLE_BUTTON(pref->control)->active;
389 if (*pref->varp.bool != bval) {
390 *pref_changed_p = TRUE;
391 *pref->varp.bool = bval;
396 if (pref->info.enum_info.radio_buttons) {
397 /* Go through the list of of radio buttons in the group, and find
398 the first one that's active. */
400 for (rb_entry = gtk_radio_button_group(GTK_RADIO_BUTTON(pref->control));
402 rb_entry = g_slist_next(rb_entry)) {
403 button = rb_entry->data;
404 if (GTK_TOGGLE_BUTTON(button)->active)
407 /* OK, now find that button's label. */
408 label = GTK_BIN(button)->child;
410 /* Get the label for the currently active entry in the option menu.
411 Yes, this is how you do it. See FAQ 6.8 in the GTK+ FAQ. */
412 label = GTK_BIN(pref->control)->child;
415 /* Get the label, and translate it to a value. */
416 gtk_label_get(GTK_LABEL(label), &label_string);
417 enumval = find_val_for_string(label_string,
418 pref->info.enum_info.enumvals, 1);
419 if (*pref->varp.enump != enumval) {
420 *pref_changed_p = TRUE;
421 *pref->varp.enump = enumval;
426 str_val = gtk_entry_get_text(GTK_ENTRY(pref->control));
427 if (*pref->varp.string == NULL || strcmp(*pref->varp.string, str_val) != 0) {
428 *pref_changed_p = TRUE;
429 if (*pref->varp.string != NULL)
430 g_free(*pref->varp.string);
431 *pref->varp.string = g_strdup(str_val);
438 module_prefs_fetch(module_t *module, gpointer user_data)
440 gboolean *must_redissect_p = user_data;
442 /* For all preferences in this module, fetch its value from this
443 module's notebook page. Find out whether any of them changed. */
444 module->prefs_changed = FALSE; /* assume none of them changed */
445 prefs_pref_foreach(module, pref_fetch, &module->prefs_changed);
447 /* If any of them changed, indicate that we must redissect and refilter
448 the current capture (if we have one), as the preference change
449 could cause packets to be dissected differently. */
450 if (module->prefs_changed)
451 *must_redissect_p = TRUE;
455 pref_clean(pref_t *pref, gpointer user_data)
457 switch (pref->type) {
469 if (pref->saved_val.string != NULL) {
470 g_free(pref->saved_val.string);
471 pref->saved_val.string = NULL;
478 module_prefs_clean(module_t *module, gpointer user_data)
480 /* For all preferences in this module, clean up any cruft allocated for
481 use by the GUI code. */
482 prefs_pref_foreach(module, pref_clean, NULL);
486 prefs_main_ok_cb(GtkWidget *ok_bt, gpointer parent_w)
488 gboolean must_redissect = FALSE;
490 /* Fetch the preferences (i.e., make sure all the values set in all of
491 the preferences panes have been copied to "prefs" and the registered
493 printer_prefs_fetch(gtk_object_get_data(GTK_OBJECT(parent_w), E_PRINT_PAGE_KEY));
494 column_prefs_fetch(gtk_object_get_data(GTK_OBJECT(parent_w), E_COLUMN_PAGE_KEY));
495 stream_prefs_fetch(gtk_object_get_data(GTK_OBJECT(parent_w), E_STREAM_PAGE_KEY));
496 gui_prefs_fetch(gtk_object_get_data(GTK_OBJECT(parent_w), E_GUI_PAGE_KEY));
497 prefs_module_foreach(module_prefs_fetch, &must_redissect);
499 /* Now apply those preferences. */
500 printer_prefs_apply(gtk_object_get_data(GTK_OBJECT(parent_w), E_PRINT_PAGE_KEY));
501 column_prefs_apply(gtk_object_get_data(GTK_OBJECT(parent_w), E_COLUMN_PAGE_KEY));
502 stream_prefs_apply(gtk_object_get_data(GTK_OBJECT(parent_w), E_STREAM_PAGE_KEY));
503 gui_prefs_apply(gtk_object_get_data(GTK_OBJECT(parent_w), E_GUI_PAGE_KEY));
506 /* Now destroy the "Preferences" dialog. */
507 gtk_widget_destroy(GTK_WIDGET(parent_w));
509 if (must_redissect) {
510 /* Redissect all the packets, and re-evaluate the display filter. */
511 redissect_packets(&cfile);
516 prefs_main_apply_cb(GtkWidget *apply_bt, gpointer parent_w)
518 gboolean must_redissect = FALSE;
520 /* Fetch the preferences (i.e., make sure all the values set in all of
521 the preferences panes have been copied to "prefs" and the registered
523 printer_prefs_fetch(gtk_object_get_data(GTK_OBJECT(parent_w), E_PRINT_PAGE_KEY));
524 column_prefs_fetch(gtk_object_get_data(GTK_OBJECT(parent_w), E_COLUMN_PAGE_KEY));
525 stream_prefs_fetch(gtk_object_get_data(GTK_OBJECT(parent_w), E_STREAM_PAGE_KEY));
526 gui_prefs_fetch(gtk_object_get_data(GTK_OBJECT(parent_w), E_GUI_PAGE_KEY));
527 prefs_module_foreach(module_prefs_fetch, &must_redissect);
529 /* Now apply those preferences. */
530 printer_prefs_apply(gtk_object_get_data(GTK_OBJECT(parent_w), E_PRINT_PAGE_KEY));
531 column_prefs_apply(gtk_object_get_data(GTK_OBJECT(parent_w), E_COLUMN_PAGE_KEY));
532 stream_prefs_apply(gtk_object_get_data(GTK_OBJECT(parent_w), E_STREAM_PAGE_KEY));
533 gui_prefs_apply(gtk_object_get_data(GTK_OBJECT(parent_w), E_GUI_PAGE_KEY));
534 prefs_module_foreach(module_prefs_fetch, &must_redissect);
537 if (must_redissect) {
538 /* Redissect all the packets, and re-evaluate the display filter. */
539 redissect_packets(&cfile);
544 prefs_main_save_cb(GtkWidget *save_bt, gpointer parent_w)
546 gboolean must_redissect = FALSE;
550 /* Fetch the preferences (i.e., make sure all the values set in all of
551 the preferences panes have been copied to "prefs" and the registered
553 printer_prefs_fetch(gtk_object_get_data(GTK_OBJECT(parent_w), E_PRINT_PAGE_KEY));
554 column_prefs_fetch(gtk_object_get_data(GTK_OBJECT(parent_w), E_COLUMN_PAGE_KEY));
555 stream_prefs_fetch(gtk_object_get_data(GTK_OBJECT(parent_w), E_STREAM_PAGE_KEY));
556 gui_prefs_fetch(gtk_object_get_data(GTK_OBJECT(parent_w), E_GUI_PAGE_KEY));
557 prefs_module_foreach(module_prefs_fetch, &must_redissect);
559 /* Write the preferencs out. */
560 err = write_prefs(&pf_path);
562 simple_dialog(ESD_TYPE_WARN, NULL,
563 "Can't open preferences file\n\"%s\": %s.", pf_path,
567 /* Now apply those preferences.
568 XXX - should we do this? The user didn't click "OK" or "Apply".
571 1) by saving the preferences they presumably indicate that they
574 2) the next time they fire Ethereal up, those preferences will
577 3) we'd have to buffer "must_redissect" so that if they do
578 "Apply" after this, we know we have to redissect;
580 4) we did apply the protocol preferences, at least, in the past. */
581 printer_prefs_apply(gtk_object_get_data(GTK_OBJECT(parent_w), E_PRINT_PAGE_KEY));
582 column_prefs_apply(gtk_object_get_data(GTK_OBJECT(parent_w), E_COLUMN_PAGE_KEY));
583 stream_prefs_apply(gtk_object_get_data(GTK_OBJECT(parent_w), E_STREAM_PAGE_KEY));
584 gui_prefs_apply(gtk_object_get_data(GTK_OBJECT(parent_w), E_GUI_PAGE_KEY));
585 prefs_module_foreach(module_prefs_fetch, &must_redissect);
588 if (must_redissect) {
589 /* Redissect all the packets, and re-evaluate the display filter. */
590 redissect_packets(&cfile);
595 pref_revert(pref_t *pref, gpointer user_data)
597 gboolean *pref_changed_p = user_data;
599 /* Revert the preference to its saved value. */
600 switch (pref->type) {
603 if (*pref->varp.uint != pref->saved_val.uint) {
604 *pref_changed_p = TRUE;
605 *pref->varp.uint = pref->saved_val.uint;
610 if (*pref->varp.bool != pref->saved_val.bool) {
611 *pref_changed_p = TRUE;
612 *pref->varp.bool = pref->saved_val.bool;
617 if (*pref->varp.enump != pref->saved_val.enumval) {
618 *pref_changed_p = TRUE;
619 *pref->varp.enump = pref->saved_val.enumval;
624 if (*pref->varp.string != pref->saved_val.string &&
625 (*pref->varp.string == NULL ||
626 pref->saved_val.string == NULL ||
627 strcmp(*pref->varp.string, pref->saved_val.string) != 0)) {
628 *pref_changed_p = TRUE;
629 if (*pref->varp.string != NULL)
630 g_free(*pref->varp.string);
631 *pref->varp.string = g_strdup(pref->saved_val.string);
638 module_prefs_revert(module_t *module, gpointer user_data)
640 gboolean *must_redissect_p = user_data;
642 /* For all preferences in this module, revert its value to the value
643 it had when we popped up the Preferences dialog. Find out whether
644 this changes any of them. */
645 module->prefs_changed = FALSE; /* assume none of them changed */
646 prefs_pref_foreach(module, pref_revert, &module->prefs_changed);
648 /* If any of them changed, indicate that we must redissect and refilter
649 the current capture (if we have one), as the preference change
650 could cause packets to be dissected differently. */
651 if (module->prefs_changed)
652 *must_redissect_p = TRUE;
656 prefs_main_cancel_cb(GtkWidget *cancel_bt, gpointer parent_w)
658 gboolean must_redissect = FALSE;
660 /* Free up the current preferences and copy the saved preferences to the
661 current preferences. */
663 copy_prefs(&prefs, &saved_prefs);
665 /* Now revert the registered preferences. */
666 prefs_module_foreach(module_prefs_revert, &must_redissect);
668 /* Now apply the reverted-to preferences. */
669 printer_prefs_apply(gtk_object_get_data(GTK_OBJECT(parent_w), E_PRINT_PAGE_KEY));
670 column_prefs_apply(gtk_object_get_data(GTK_OBJECT(parent_w), E_COLUMN_PAGE_KEY));
671 stream_prefs_apply(gtk_object_get_data(GTK_OBJECT(parent_w), E_STREAM_PAGE_KEY));
672 gui_prefs_apply(gtk_object_get_data(GTK_OBJECT(parent_w), E_GUI_PAGE_KEY));
675 gtk_widget_destroy(GTK_WIDGET(parent_w));
677 if (must_redissect) {
678 /* Redissect all the packets, and re-evaluate the display filter. */
679 redissect_packets(&cfile);
683 /* Treat this as a cancel, by calling "prefs_main_cancel_cb()".
684 XXX - that'll destroy the Preferences dialog; will that upset
685 a higher-level handler that says "OK, we've been asked to delete
686 this, so destroy it"? */
688 prefs_main_delete_cb(GtkWidget *prefs_w, gpointer dummy)
690 prefs_main_cancel_cb(NULL, prefs_w);
695 prefs_main_destroy_cb(GtkWidget *win, gpointer user_data)
697 /* Let the preference tabs clean up anything they've done. */
698 printer_prefs_destroy(gtk_object_get_data(GTK_OBJECT(prefs_w), E_PRINT_PAGE_KEY));
699 column_prefs_destroy(gtk_object_get_data(GTK_OBJECT(prefs_w), E_COLUMN_PAGE_KEY));
700 stream_prefs_destroy(gtk_object_get_data(GTK_OBJECT(prefs_w), E_STREAM_PAGE_KEY));
701 gui_prefs_destroy(gtk_object_get_data(GTK_OBJECT(prefs_w), E_GUI_PAGE_KEY));
703 /* Free up the saved preferences (both for "prefs" and for registered
705 free_prefs(&saved_prefs);
706 prefs_module_foreach(module_prefs_clean, NULL);
708 /* Note that we no longer have a "Preferences" dialog box. */
712 struct properties_data {
718 /* XXX this way of searching the correct page number is really ugly ... */
720 module_search_properties(module_t *module, gpointer user_data)
722 struct properties_data *p = (struct properties_data *)user_data;
724 if (p->title == NULL) return;
725 if (strcmp(module->title, p->title) == 0) {
727 gtk_notebook_set_page(GTK_NOTEBOOK(p->w), p->page_num);
735 properties_cb(GtkWidget *w, gpointer dummy)
738 struct properties_data p;
740 if (finfo_selected) {
741 header_field_info *hfinfo = finfo_selected->hfinfo;
742 if (hfinfo->parent == -1) {
743 title = (gchar *)prefs_get_title_by_name(hfinfo->abbrev);
746 prefs_get_title_by_name(proto_registrar_get_abbrev(hfinfo->parent));
754 if (prefs_w != NULL) {
755 reactivate_window(prefs_w);
761 p.page_num = FIRST_PROTO_PREFS_PAGE;
764 prefs_module_foreach(module_search_properties, &p);