Support putting preferences into arbitrary places in a tree, which is
used to construct the "Edit->Preferences" dialog box; this includes the ability to register a "subtree" for preferences. Instead of special-casing protocol preferences, have a subtree "Protocols" for protocol preferences. svn path=/trunk/; revision=6808
This commit is contained in:
parent
e4633bc783
commit
392fee6d7a
177
gtk/prefs_dlg.c
177
gtk/prefs_dlg.c
|
@ -1,7 +1,7 @@
|
|||
/* prefs_dlg.c
|
||||
* Routines for handling preferences
|
||||
*
|
||||
* $Id: prefs_dlg.c,v 1.56 2002/11/28 01:58:27 guy Exp $
|
||||
* $Id: prefs_dlg.c,v 1.57 2002/12/20 01:48:57 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -78,7 +78,7 @@ static void prefs_tree_select_cb(GtkTreeSelection *, gpointer);
|
|||
#define E_NAMERES_PAGE_KEY "nameres_options_page"
|
||||
#define E_TOOLTIPS_KEY "tooltips"
|
||||
|
||||
#define FIRST_PROTO_PREFS_PAGE 6
|
||||
static int first_proto_prefs_page = -1;
|
||||
|
||||
/*
|
||||
* Keep a static pointer to the notebook to be able to choose the
|
||||
|
@ -102,14 +102,17 @@ static GtkWidget *prefs_w;
|
|||
static e_prefs saved_prefs;
|
||||
|
||||
struct ct_struct {
|
||||
GtkWidget *main_vb;
|
||||
GtkWidget *notebook;
|
||||
GtkWidget *tree;
|
||||
#if GTK_MAJOR_VERSION >= 2
|
||||
GtkTreeIter proto_iter;
|
||||
#endif
|
||||
#if GTK_MAJOR_VERSION < 2
|
||||
GtkCTreeNode *node;
|
||||
#else
|
||||
GtkTreeIter iter;
|
||||
#endif
|
||||
GtkTooltips *tooltips;
|
||||
gint page;
|
||||
gboolean is_protocol;
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -203,57 +206,108 @@ static void
|
|||
module_prefs_show(module_t *module, gpointer user_data)
|
||||
{
|
||||
struct ct_struct *cts = user_data;
|
||||
struct ct_struct child_cts;
|
||||
GtkWidget *main_vb, *main_tb, *frame;
|
||||
gchar label_str[MAX_TREE_NODE_NAME_LEN];
|
||||
#if GTK_MAJOR_VERSION < 2
|
||||
gchar *label_ptr = label_str;
|
||||
gchar *label_ptr = label_str;
|
||||
GtkCTreeNode *ct_node;
|
||||
#else
|
||||
GtkTreeStore *model;
|
||||
GtkTreeIter iter;
|
||||
#endif
|
||||
|
||||
/* Frame */
|
||||
frame = gtk_frame_new(module->title);
|
||||
gtk_widget_show(frame);
|
||||
|
||||
/* Main vertical box */
|
||||
main_vb = gtk_vbox_new(FALSE, 5);
|
||||
gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
|
||||
gtk_container_add(GTK_CONTAINER(frame), main_vb);
|
||||
|
||||
/* Main table */
|
||||
main_tb = gtk_table_new(module->numprefs, 2, FALSE);
|
||||
gtk_box_pack_start(GTK_BOX(main_vb), main_tb, FALSE, FALSE, 0);
|
||||
gtk_table_set_row_spacings(GTK_TABLE(main_tb), 10);
|
||||
gtk_table_set_col_spacings(GTK_TABLE(main_tb), 15);
|
||||
OBJECT_SET_DATA(main_tb, E_TOOLTIPS_KEY, cts->tooltips);
|
||||
|
||||
/* Add items for each of the preferences */
|
||||
prefs_pref_foreach(module, pref_show, main_tb);
|
||||
|
||||
gtk_notebook_append_page(GTK_NOTEBOOK(cts->notebook), frame, NULL);
|
||||
/*
|
||||
* Add this module to the tree.
|
||||
*/
|
||||
strcpy(label_str, module->title);
|
||||
#if GTK_MAJOR_VERSION < 2
|
||||
ct_node = gtk_ctree_insert_node(GTK_CTREE(cts->tree), cts->node, NULL,
|
||||
&label_ptr, 5, NULL, NULL, NULL, NULL, TRUE, TRUE);
|
||||
gtk_ctree_node_set_row_data(GTK_CTREE(cts->tree), ct_node,
|
||||
GINT_TO_POINTER(cts->page));
|
||||
&label_ptr, 5, NULL, NULL, NULL, NULL, !module->is_subtree,
|
||||
FALSE);
|
||||
#else
|
||||
model = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(cts->tree)));
|
||||
gtk_tree_store_append(model, &iter, &cts->proto_iter);
|
||||
gtk_tree_store_set(model, &iter, 0, label_str, 1, cts->page, -1);
|
||||
gtk_tree_store_append(model, &iter, &cts->iter);
|
||||
#endif
|
||||
cts->page++;
|
||||
|
||||
/* Show 'em what we got */
|
||||
gtk_widget_show_all(main_vb);
|
||||
/*
|
||||
* Is this a subtree?
|
||||
*/
|
||||
if (module->is_subtree) {
|
||||
/*
|
||||
* Yes.
|
||||
*/
|
||||
|
||||
/* Note that there's no page attached to this item */
|
||||
#if GTK_MAJOR_VERSION < 2
|
||||
gtk_ctree_node_set_row_data(GTK_CTREE(cts->tree), ct_node,
|
||||
GINT_TO_POINTER(-1));
|
||||
#else
|
||||
gtk_tree_store_set(model, &iter, 0, label_str, 1, -1, -1);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Walk the subtree and attach stuff to it.
|
||||
*/
|
||||
child_cts = *cts;
|
||||
#if GTK_MAJOR_VERSION < 2
|
||||
child_cts.node = ct_node;
|
||||
#else
|
||||
child_cts.iter = iter;
|
||||
#endif
|
||||
if (module == protocols_module)
|
||||
child_cts.is_protocol = TRUE;
|
||||
prefs_module_list_foreach(module->prefs, module_prefs_show, &child_cts);
|
||||
} else {
|
||||
/*
|
||||
* No.
|
||||
* Create a notebook page for it.
|
||||
*/
|
||||
|
||||
/* Frame */
|
||||
frame = gtk_frame_new(module->title);
|
||||
gtk_widget_show(frame);
|
||||
|
||||
/* Main vertical box */
|
||||
main_vb = gtk_vbox_new(FALSE, 5);
|
||||
gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
|
||||
gtk_container_add(GTK_CONTAINER(frame), main_vb);
|
||||
|
||||
/* Main table */
|
||||
main_tb = gtk_table_new(module->numprefs, 2, FALSE);
|
||||
gtk_box_pack_start(GTK_BOX(main_vb), main_tb, FALSE, FALSE, 0);
|
||||
gtk_table_set_row_spacings(GTK_TABLE(main_tb), 10);
|
||||
gtk_table_set_col_spacings(GTK_TABLE(main_tb), 15);
|
||||
OBJECT_SET_DATA(main_tb, E_TOOLTIPS_KEY, cts->tooltips);
|
||||
|
||||
/* Add items for each of the preferences */
|
||||
prefs_pref_foreach(module, pref_show, main_tb);
|
||||
|
||||
/* Add the page to the notebook */
|
||||
gtk_notebook_append_page(GTK_NOTEBOOK(cts->notebook), frame, NULL);
|
||||
|
||||
/* Attach the page to the tree item */
|
||||
#if GTK_MAJOR_VERSION < 2
|
||||
gtk_ctree_node_set_row_data(GTK_CTREE(cts->tree), ct_node,
|
||||
GINT_TO_POINTER(cts->page));
|
||||
#else
|
||||
gtk_tree_store_set(model, &iter, 0, label_str, 1, cts->page, -1);
|
||||
#endif
|
||||
|
||||
/* If this is the first protocol page, remember its page number */
|
||||
if (first_proto_prefs_page == -1)
|
||||
first_proto_prefs_page = cts->page;
|
||||
cts->page++;
|
||||
|
||||
/* Show 'em what we got */
|
||||
gtk_widget_show_all(main_vb);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
prefs_cb(GtkWidget *w _U_, gpointer dummy _U_)
|
||||
{
|
||||
GtkWidget *main_vb, *top_hb, *bbox, *prefs_nb, *ct_sb, *frame,
|
||||
GtkWidget *top_hb, *bbox, *prefs_nb, *ct_sb, *frame,
|
||||
*ok_bt, *apply_bt, *save_bt, *cancel_bt;
|
||||
GtkWidget *print_pg, *column_pg, *stream_pg, *gui_pg;
|
||||
#ifdef HAVE_LIBPCAP
|
||||
|
@ -266,7 +320,6 @@ prefs_cb(GtkWidget *w _U_, gpointer dummy _U_)
|
|||
gchar *label_ptr = label_str;
|
||||
GtkCTreeNode *ct_node;
|
||||
#else
|
||||
GtkTreeStore *store;
|
||||
GtkTreeSelection *selection;
|
||||
GtkCellRenderer *renderer;
|
||||
GtkTreeViewColumn *column;
|
||||
|
@ -297,14 +350,14 @@ prefs_cb(GtkWidget *w _U_, gpointer dummy _U_)
|
|||
cts.tooltips = gtk_tooltips_new();
|
||||
|
||||
/* Container for each row of widgets */
|
||||
main_vb = gtk_vbox_new(FALSE, 5);
|
||||
gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
|
||||
gtk_container_add(GTK_CONTAINER(prefs_w), main_vb);
|
||||
gtk_widget_show(main_vb);
|
||||
cts.main_vb = gtk_vbox_new(FALSE, 5);
|
||||
gtk_container_border_width(GTK_CONTAINER(cts.main_vb), 5);
|
||||
gtk_container_add(GTK_CONTAINER(prefs_w), cts.main_vb);
|
||||
gtk_widget_show(cts.main_vb);
|
||||
|
||||
/* Top row: Preferences tree and notebook */
|
||||
top_hb = gtk_hbox_new(FALSE, 10);
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), top_hb);
|
||||
gtk_container_add(GTK_CONTAINER(cts.main_vb), top_hb);
|
||||
gtk_widget_show(top_hb);
|
||||
|
||||
/* Place a Ctree on the left for preference categories */
|
||||
|
@ -331,7 +384,8 @@ prefs_cb(GtkWidget *w _U_, gpointer dummy _U_)
|
|||
gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(column),
|
||||
GTK_TREE_VIEW_COLUMN_AUTOSIZE);
|
||||
#endif
|
||||
cts.page = 0;
|
||||
cts.page = 0;
|
||||
cts.node = NULL;
|
||||
gtk_container_add(GTK_CONTAINER(ct_sb), cts.tree);
|
||||
|
||||
#if GTK_MAJOR_VERSION < 2
|
||||
|
@ -344,8 +398,8 @@ prefs_cb(GtkWidget *w _U_, gpointer dummy _U_)
|
|||
|
||||
/* A notebook widget sans tabs is used to flip between prefs */
|
||||
notebook = prefs_nb = gtk_notebook_new();
|
||||
gtk_notebook_set_show_tabs(GTK_NOTEBOOK(notebook), FALSE);
|
||||
gtk_notebook_set_show_border(GTK_NOTEBOOK(notebook), FALSE);
|
||||
gtk_notebook_set_show_tabs(GTK_NOTEBOOK(prefs_nb), FALSE);
|
||||
gtk_notebook_set_show_border(GTK_NOTEBOOK(prefs_nb), FALSE);
|
||||
gtk_container_add(GTK_CONTAINER(top_hb), prefs_nb);
|
||||
gtk_widget_show(prefs_nb);
|
||||
|
||||
|
@ -474,26 +528,14 @@ prefs_cb(GtkWidget *w _U_, gpointer dummy _U_)
|
|||
|
||||
/* Registered prefs */
|
||||
cts.notebook = prefs_nb;
|
||||
strcpy(label_str, "Protocols");
|
||||
#if GTK_MAJOR_VERSION < 2
|
||||
cts.node = gtk_ctree_insert_node(GTK_CTREE(cts.tree), NULL, NULL,
|
||||
&label_ptr, 5, NULL, NULL, NULL, NULL, FALSE, FALSE);
|
||||
gtk_ctree_node_set_row_data(GTK_CTREE(cts.tree), cts.node,
|
||||
GINT_TO_POINTER(-1));
|
||||
gtk_ctree_node_set_selectable(GTK_CTREE(cts.tree), cts.node, FALSE);
|
||||
#else
|
||||
gtk_tree_store_append(store, &cts.proto_iter, NULL);
|
||||
gtk_tree_store_set(store, &cts.proto_iter, 0, label_str, 1, -1, -1);
|
||||
#endif
|
||||
|
||||
prefs_module_foreach(module_prefs_show, &cts);
|
||||
|
||||
cts.is_protocol = FALSE;
|
||||
prefs_module_list_foreach(NULL, module_prefs_show, &cts);
|
||||
|
||||
/* Button row: OK and cancel buttons */
|
||||
bbox = gtk_hbutton_box_new();
|
||||
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
|
||||
gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
|
||||
gtk_container_add(GTK_CONTAINER(main_vb), bbox);
|
||||
gtk_container_add(GTK_CONTAINER(cts.main_vb), bbox);
|
||||
gtk_widget_show(bbox);
|
||||
|
||||
#if GTK_MAJOR_VERSION < 2
|
||||
|
@ -914,7 +956,7 @@ prefs_main_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w)
|
|||
#endif /* _WIN32 */
|
||||
#endif /* HAVE_LIBPCAP */
|
||||
nameres_prefs_fetch(OBJECT_GET_DATA(parent_w, E_NAMERES_PAGE_KEY));
|
||||
prefs_module_foreach(module_prefs_fetch, &must_redissect);
|
||||
prefs_modules_foreach(module_prefs_fetch, &must_redissect);
|
||||
|
||||
/* Now apply those preferences. */
|
||||
printer_prefs_apply(OBJECT_GET_DATA(parent_w, E_PRINT_PAGE_KEY));
|
||||
|
@ -966,7 +1008,7 @@ prefs_main_apply_cb(GtkWidget *apply_bt _U_, gpointer parent_w)
|
|||
#endif /* _WIN32 */
|
||||
#endif /* HAVE_LIBPCAP */
|
||||
nameres_prefs_fetch(OBJECT_GET_DATA(parent_w, E_NAMERES_PAGE_KEY));
|
||||
prefs_module_foreach(module_prefs_fetch, &must_redissect);
|
||||
prefs_modules_foreach(module_prefs_fetch, &must_redissect);
|
||||
|
||||
/* Now apply those preferences. */
|
||||
printer_prefs_apply(OBJECT_GET_DATA(parent_w, E_PRINT_PAGE_KEY));
|
||||
|
@ -1018,7 +1060,7 @@ prefs_main_save_cb(GtkWidget *save_bt _U_, gpointer parent_w)
|
|||
#endif /* _WIN32 */
|
||||
#endif /* HAVE_LIBPCAP */
|
||||
nameres_prefs_fetch(OBJECT_GET_DATA(parent_w, E_NAMERES_PAGE_KEY));
|
||||
prefs_module_foreach(module_prefs_fetch, &must_redissect);
|
||||
prefs_modules_foreach(module_prefs_fetch, &must_redissect);
|
||||
|
||||
/* Create the directory that holds personal configuration files, if
|
||||
necessary. */
|
||||
|
@ -1151,7 +1193,7 @@ prefs_main_cancel_cb(GtkWidget *cancel_bt _U_, gpointer parent_w)
|
|||
copy_prefs(&prefs, &saved_prefs);
|
||||
|
||||
/* Now revert the registered preferences. */
|
||||
prefs_module_foreach(module_prefs_revert, &must_redissect);
|
||||
prefs_modules_foreach(module_prefs_revert, &must_redissect);
|
||||
|
||||
/* Now apply the reverted-to preferences. */
|
||||
printer_prefs_apply(OBJECT_GET_DATA(parent_w, E_PRINT_PAGE_KEY));
|
||||
|
@ -1203,10 +1245,11 @@ prefs_main_destroy_cb(GtkWidget *win _U_, gpointer user_data _U_)
|
|||
/* Free up the saved preferences (both for "prefs" and for registered
|
||||
preferences). */
|
||||
free_prefs(&saved_prefs);
|
||||
prefs_module_foreach(module_prefs_clean, NULL);
|
||||
prefs_modules_foreach(module_prefs_clean, NULL);
|
||||
|
||||
/* Note that we no longer have a "Preferences" dialog box. */
|
||||
prefs_w = NULL;
|
||||
first_proto_prefs_page = -1;
|
||||
}
|
||||
|
||||
struct properties_data {
|
||||
|
@ -1258,11 +1301,11 @@ properties_cb(GtkWidget *w, gpointer dummy)
|
|||
}
|
||||
|
||||
p.w = notebook;
|
||||
p.page_num = FIRST_PROTO_PREFS_PAGE;
|
||||
p.page_num = first_proto_prefs_page;
|
||||
p.title = title;
|
||||
|
||||
prefs_module_foreach(module_search_properties, &p);
|
||||
|
||||
prefs_module_list_foreach(protocols_module->prefs, module_search_properties,
|
||||
&p);
|
||||
}
|
||||
|
||||
/* Prefs tree selection callback. The node data has been loaded with
|
||||
|
|
10
prefs-int.h
10
prefs-int.h
|
@ -2,7 +2,7 @@
|
|||
* Definitions for implementation of preference handling routines;
|
||||
* used by "friends" of the preferences type.
|
||||
*
|
||||
* $Id: prefs-int.h,v 1.9 2002/08/28 21:00:40 jmayer Exp $
|
||||
* $Id: prefs-int.h,v 1.10 2002/12/20 01:48:54 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -29,14 +29,20 @@
|
|||
struct pref_module {
|
||||
const char *name; /* name of module */
|
||||
const char *title; /* title of module (displayed in preferences notebook) */
|
||||
gboolean is_subtree; /* if TRUE, this has other modules, not preferences, under it */
|
||||
void (*apply_cb)(void); /* routine to call when preferences applied */
|
||||
GList *prefs; /* list of its preferences */
|
||||
GList *prefs; /* list of its preferences or submodules */
|
||||
int numprefs; /* number of non-obsolete preferences */
|
||||
gboolean prefs_changed; /* if TRUE, a preference has changed since we last checked */
|
||||
gboolean obsolete; /* if TRUE, this is a module that used to
|
||||
exist but no longer does */
|
||||
};
|
||||
|
||||
/*
|
||||
* Module used for protocol preferences.
|
||||
*/
|
||||
extern module_t *protocols_module;
|
||||
|
||||
/*
|
||||
* PREF_OBSOLETE is used for preferences that a module used to support
|
||||
* but no longer supports; we give different error messages for them.
|
||||
|
|
196
prefs.c
196
prefs.c
|
@ -1,7 +1,7 @@
|
|||
/* prefs.c
|
||||
* Routines for handling preferences
|
||||
*
|
||||
* $Id: prefs.c,v 1.91 2002/09/28 15:23:13 gerald Exp $
|
||||
* $Id: prefs.c,v 1.92 2002/12/20 01:48:54 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -51,6 +51,9 @@
|
|||
|
||||
/* Internal functions */
|
||||
static module_t *find_module(const char *name);
|
||||
static module_t *prefs_register_module_or_subtree(module_t *parent,
|
||||
const char *name, const char *title, gboolean is_subtree,
|
||||
void (*apply_cb)(void));
|
||||
static struct preference *find_preference(module_t *, const char *);
|
||||
static int set_pref(gchar*, gchar*);
|
||||
static GList *get_string_list(gchar *);
|
||||
|
@ -85,10 +88,16 @@ gchar *gui_hex_dump_highlight_style_text[] =
|
|||
{ "BOLD", "INVERSE", NULL };
|
||||
|
||||
/*
|
||||
* List of modules with preference settings.
|
||||
* List of all modules with preference settings.
|
||||
*/
|
||||
static GList *modules;
|
||||
|
||||
/*
|
||||
* List of all modules that should show up at the top level of the
|
||||
* tree in the preference dialog box.
|
||||
*/
|
||||
static GList *top_level_modules;
|
||||
|
||||
static gint
|
||||
module_compare_name(gconstpointer p1_arg, gconstpointer p2_arg)
|
||||
{
|
||||
|
@ -98,15 +107,46 @@ module_compare_name(gconstpointer p1_arg, gconstpointer p2_arg)
|
|||
return g_strcasecmp(p1->name, p2->name);
|
||||
}
|
||||
|
||||
static gint
|
||||
module_compare_title(gconstpointer p1_arg, gconstpointer p2_arg)
|
||||
{
|
||||
const module_t *p1 = p1_arg;
|
||||
const module_t *p2 = p2_arg;
|
||||
|
||||
return g_strcasecmp(p1->title, p2->title);
|
||||
}
|
||||
|
||||
/*
|
||||
* Register a module that will have preferences.
|
||||
* Specify the name used for the module in the preferences file, the
|
||||
* title used in the tab for it in a preferences dialog box, and a
|
||||
* Specify the module under which to register it or NULL to register it
|
||||
* at the top level, the name used for the module in the preferences file,
|
||||
* the title used in the tab for it in a preferences dialog box, and a
|
||||
* routine to call back when we apply the preferences.
|
||||
*/
|
||||
module_t *
|
||||
prefs_register_module(const char *name, const char *title,
|
||||
prefs_register_module(module_t *parent, const char *name, const char *title,
|
||||
void (*apply_cb)(void))
|
||||
{
|
||||
return prefs_register_module_or_subtree(parent, name, title, FALSE,
|
||||
apply_cb);
|
||||
}
|
||||
|
||||
/*
|
||||
* Register a subtree that will have modules under it.
|
||||
* Specify the module under which to register it or NULL to register it
|
||||
* at the top level and the title used in the tab for it in a preferences
|
||||
* dialog box.
|
||||
*/
|
||||
module_t *
|
||||
prefs_register_subtree(module_t *parent, const char *title)
|
||||
{
|
||||
return prefs_register_module_or_subtree(parent, NULL, title, TRUE,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static module_t *
|
||||
prefs_register_module_or_subtree(module_t *parent, const char *name,
|
||||
const char *title, gboolean is_subtree, void (*apply_cb)(void))
|
||||
{
|
||||
module_t *module;
|
||||
const guchar *p;
|
||||
|
@ -114,6 +154,7 @@ prefs_register_module(const char *name, const char *title,
|
|||
module = g_malloc(sizeof (module_t));
|
||||
module->name = name;
|
||||
module->title = title;
|
||||
module->is_subtree = is_subtree;
|
||||
module->apply_cb = apply_cb;
|
||||
module->prefs = NULL; /* no preferences, to start */
|
||||
module->numprefs = 0;
|
||||
|
@ -121,28 +162,69 @@ prefs_register_module(const char *name, const char *title,
|
|||
module->obsolete = FALSE;
|
||||
|
||||
/*
|
||||
* Make sure that only lower-case ASCII letters, numbers,
|
||||
* underscores, and dots appear in the module name.
|
||||
*
|
||||
* Crash if there is, as that's an error in the code;
|
||||
* you can make the title a nice string with capitalization,
|
||||
* white space, punctuation, etc., but the name can be used
|
||||
* on the command line, and shouldn't require quoting,
|
||||
* shifting, etc.
|
||||
* Do we have a module name?
|
||||
*/
|
||||
for (p = name; *p != '\0'; p++)
|
||||
g_assert(isascii(*p) &&
|
||||
(islower(*p) || isdigit(*p) || *p == '_' || *p == '.'));
|
||||
if (name != NULL) {
|
||||
/*
|
||||
* Yes.
|
||||
* Make sure that only lower-case ASCII letters, numbers,
|
||||
* underscores, and dots appear in the name.
|
||||
*
|
||||
* Crash if there is, as that's an error in the code;
|
||||
* you can make the title a nice string with capitalization,
|
||||
* white space, punctuation, etc., but the name can be used
|
||||
* on the command line, and shouldn't require quoting,
|
||||
* shifting, etc.
|
||||
*/
|
||||
for (p = name; *p != '\0'; p++)
|
||||
g_assert(isascii(*p) &&
|
||||
(islower(*p) || isdigit(*p) || *p == '_' ||
|
||||
*p == '.'));
|
||||
|
||||
/*
|
||||
* Make sure there's not already a module with that
|
||||
* name. Crash if there is, as that's an error in the
|
||||
* code, and the code has to be fixed not to register
|
||||
* more than one module with the same name.
|
||||
*
|
||||
* We search the list of all modules; the subtree stuff
|
||||
* doesn't require preferences in subtrees to have names
|
||||
* that reflect the subtree they're in (that would require
|
||||
* protocol preferences to have a bogus "protocol.", or
|
||||
* something such as that, to be added to all their names).
|
||||
*/
|
||||
g_assert(find_module(name) == NULL);
|
||||
|
||||
/*
|
||||
* Insert this module in the list of all modules.
|
||||
*/
|
||||
modules = g_list_insert_sorted(modules, module,
|
||||
module_compare_name);
|
||||
} else {
|
||||
/*
|
||||
* This has no name, just a title; check to make sure it's a
|
||||
* subtree, and crash if it's not.
|
||||
*/
|
||||
g_assert(is_subtree);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure there's not already a module with that
|
||||
* name. Crash if there is, as that's an error in the
|
||||
* code, and the code has to be fixed not to register
|
||||
* more than one module with the same name.
|
||||
* Insert this module into the appropriate place in the display
|
||||
* tree.
|
||||
*/
|
||||
g_assert(find_module(name) == NULL);
|
||||
|
||||
modules = g_list_insert_sorted(modules, module, module_compare_name);
|
||||
if (parent == NULL) {
|
||||
/*
|
||||
* It goes at the top.
|
||||
*/
|
||||
top_level_modules = g_list_insert_sorted(top_level_modules,
|
||||
module, module_compare_title);
|
||||
} else {
|
||||
/*
|
||||
* It goes into the list for this module.
|
||||
*/
|
||||
parent->prefs = g_list_insert_sorted(parent->prefs, module,
|
||||
module_compare_title);
|
||||
}
|
||||
|
||||
return module;
|
||||
}
|
||||
|
@ -150,12 +232,23 @@ prefs_register_module(const char *name, const char *title,
|
|||
/*
|
||||
* Register that a protocol has preferences.
|
||||
*/
|
||||
module_t *protocols_module;
|
||||
|
||||
module_t *
|
||||
prefs_register_protocol(int id, void (*apply_cb)(void))
|
||||
{
|
||||
return prefs_register_module(proto_get_protocol_filter_name(id),
|
||||
proto_get_protocol_short_name(id),
|
||||
apply_cb);
|
||||
/*
|
||||
* Have we yet created the "Protocols" subtree?
|
||||
*/
|
||||
if (protocols_module == NULL) {
|
||||
/*
|
||||
* No. Do so.
|
||||
*/
|
||||
protocols_module = prefs_register_subtree(NULL, "Protocols");
|
||||
}
|
||||
return prefs_register_module(protocols_module,
|
||||
proto_get_protocol_filter_name(id),
|
||||
proto_get_protocol_short_name(id), apply_cb);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -167,9 +260,18 @@ prefs_register_protocol_obsolete(int id)
|
|||
{
|
||||
module_t *module;
|
||||
|
||||
module = prefs_register_module(proto_get_protocol_filter_name(id),
|
||||
proto_get_protocol_short_name(id),
|
||||
NULL);
|
||||
/*
|
||||
* Have we yet created the "Protocols" subtree?
|
||||
*/
|
||||
if (protocols_module == NULL) {
|
||||
/*
|
||||
* No. Do so.
|
||||
*/
|
||||
protocols_module = prefs_register_subtree(NULL, "Protocols");
|
||||
}
|
||||
module = prefs_register_module(protocols_module,
|
||||
proto_get_protocol_filter_name(id),
|
||||
proto_get_protocol_short_name(id), NULL);
|
||||
module->obsolete = TRUE;
|
||||
return module;
|
||||
}
|
||||
|
@ -213,19 +315,41 @@ do_module_callback(gpointer data, gpointer user_data)
|
|||
}
|
||||
|
||||
/*
|
||||
* Call a callback function, with a specified argument, for each module.
|
||||
* Call a callback function, with a specified argument, for each module
|
||||
* in a list of modules. If the list is NULL, searches the top-level
|
||||
* list in the display tree of modules.
|
||||
*
|
||||
* Ignores "obsolete" modules; their sole purpose is to allow old
|
||||
* preferences for dissectors that no longer have preferences to be
|
||||
* silently ignored in preference files. Does not ignore subtrees,
|
||||
* as this can be used when walking the display tree of modules.
|
||||
*/
|
||||
void
|
||||
prefs_module_list_foreach(GList *module_list, module_cb callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
module_cb_arg_t arg;
|
||||
|
||||
if (module_list == NULL)
|
||||
module_list = top_level_modules;
|
||||
|
||||
arg.callback = callback;
|
||||
arg.user_data = user_data;
|
||||
g_list_foreach(module_list, do_module_callback, &arg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Call a callback function, with a specified argument, for each module
|
||||
* in the list of all modules. (This list does not include subtrees.)
|
||||
*
|
||||
* Ignores "obsolete" modules; their sole purpose is to allow old
|
||||
* preferences for dissectors that no longer have preferences to be
|
||||
* silently ignored in preference files.
|
||||
*/
|
||||
void
|
||||
prefs_module_foreach(module_cb callback, gpointer user_data)
|
||||
prefs_modules_foreach(module_cb callback, gpointer user_data)
|
||||
{
|
||||
module_cb_arg_t arg;
|
||||
|
||||
arg.callback = callback;
|
||||
arg.user_data = user_data;
|
||||
g_list_foreach(modules, do_module_callback, &arg);
|
||||
prefs_module_list_foreach(modules, callback, user_data);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
53
prefs.h
53
prefs.h
|
@ -1,7 +1,7 @@
|
|||
/* prefs.h
|
||||
* Definitions for preference handling routines
|
||||
*
|
||||
* $Id: prefs.h,v 1.41 2002/09/14 10:07:37 oabad Exp $
|
||||
* $Id: prefs.h,v 1.42 2002/12/20 01:48:54 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -88,18 +88,27 @@ typedef struct pref_module module_t;
|
|||
|
||||
/*
|
||||
* Register a module that will have preferences.
|
||||
* Specify the name used for the module in the preferences file, the
|
||||
* title used in the tab for it in a preferences dialog box, and a
|
||||
* Specify the module under which to register it or NULL to register it
|
||||
* at the top level, the name used for the module in the preferences file,
|
||||
* the title used in the tab for it in a preferences dialog box, and a
|
||||
* routine to call back when we apply the preferences.
|
||||
* Note:
|
||||
* In case of dissectors, the specified name should be the protocol
|
||||
* name specified at the proto_register_protocol() call in order to
|
||||
* make the "Protocol Properties..." menu item work.
|
||||
*
|
||||
* This should not be used for dissector preferences;
|
||||
* "prefs_register_protocol()" should be used for that, so that the
|
||||
* preferences go under the "Protocols" subtree, and so that the
|
||||
* name is the protocol name specified at the "proto_register_protocol()"
|
||||
* call so that the "Protocol Properties..." menu item works.
|
||||
*/
|
||||
extern module_t *prefs_register_module(const char *name, const char *title,
|
||||
void (*apply_cb)(void));
|
||||
extern module_t *prefs_register_module(module_t *parent, const char *name,
|
||||
const char *title, void (*apply_cb)(void));
|
||||
|
||||
typedef void (*module_cb)(module_t *module, gpointer user_data);
|
||||
/*
|
||||
* Register a subtree that will have modules under it.
|
||||
* Specify the module under which to register it or NULL to register it
|
||||
* at the top level and the title used in the tab for it in a preferences
|
||||
* dialog box.
|
||||
*/
|
||||
extern module_t *prefs_register_subtree(module_t *parent, const char *title);
|
||||
|
||||
/*
|
||||
* Register that a protocol has preferences.
|
||||
|
@ -113,12 +122,32 @@ extern module_t *prefs_register_protocol(int id, void (*apply_cb)(void));
|
|||
extern module_t *prefs_register_protocol_obsolete(int id);
|
||||
|
||||
/*
|
||||
* Call a callback function, with a specified argument, for each module.
|
||||
* Callback function for module list scanners.
|
||||
*/
|
||||
typedef void (*module_cb)(module_t *module, gpointer user_data);
|
||||
|
||||
/*
|
||||
* Call a callback function, with a specified argument, for each module
|
||||
* in a list of modules. If the list is NULL, searches the top-level
|
||||
* list in the display tree of modules.
|
||||
*
|
||||
* Ignores "obsolete" modules; their sole purpose is to allow old
|
||||
* preferences for dissectors that no longer have preferences to be
|
||||
* silently ignored in preference files. Does not ignore subtrees,
|
||||
* as this can be used when walking the display tree of modules.
|
||||
*/
|
||||
extern void prefs_module_list_foreach(GList *module_list, module_cb callback,
|
||||
gpointer user_data);
|
||||
|
||||
/*
|
||||
* Call a callback function, with a specified argument, for each module
|
||||
* in the list of all modules. (This list does not include subtrees.)
|
||||
*
|
||||
* Ignores "obsolete" modules; their sole purpose is to allow old
|
||||
* preferences for dissectors that no longer have preferences to be
|
||||
* silently ignored in preference files.
|
||||
*/
|
||||
extern void prefs_module_foreach(module_cb callback, gpointer user_data);
|
||||
extern void prefs_modules_foreach(module_cb callback, gpointer user_data);
|
||||
|
||||
/*
|
||||
* Call the "apply" callback function for each module if any of its
|
||||
|
|
Loading…
Reference in New Issue