diff options
-rw-r--r-- | epan/prefs-int.h | 4 | ||||
-rw-r--r-- | epan/prefs.c | 101 | ||||
-rw-r--r-- | epan/prefs.h | 8 | ||||
-rw-r--r-- | gtk/prefs_dlg.c | 92 |
4 files changed, 167 insertions, 38 deletions
diff --git a/epan/prefs-int.h b/epan/prefs-int.h index 547ae36742..7603049fc7 100644 --- a/epan/prefs-int.h +++ b/epan/prefs-int.h @@ -30,9 +30,9 @@ struct pref_module { const char *name; /* name of module */ const char *title; /* title of module (displayed in preferences list) */ const char *description;/* Description 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 or submodules */ + GList *prefs; /* list of its preferences */ + GList *submodules; /* list of its 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 diff --git a/epan/prefs.c b/epan/prefs.c index 309d876567..2dd47070a1 100644 --- a/epan/prefs.c +++ b/epan/prefs.c @@ -51,6 +51,7 @@ #include <epan/uat-int.h> /* Internal functions */ +static module_t *find_subtree(module_t *parent, const char *name); static module_t *prefs_register_module_or_subtree(module_t *parent, const char *name, const char *title, const char *description, gboolean is_subtree, void (*apply_cb)(void)); @@ -166,13 +167,27 @@ prefs_register_module_or_subtree(module_t *parent, const char *name, const char *p; guchar c; + /* this module may have been created as a subtree item previously */ + if(module = find_subtree(parent, title)) { + /* the module is currently a subtree */ + module->name = name; + module->apply_cb = apply_cb; + module->description = description; + + if(prefs_find_module(name) == NULL) + modules = g_list_insert_sorted(modules, module, + module_compare_name); + + return module; + } + module = g_malloc(sizeof (module_t)); module->name = name; module->title = title; module->description = description; - module->is_subtree = is_subtree; module->apply_cb = apply_cb; module->prefs = NULL; /* no preferences, to start */ + module->submodules = NULL; /* no submodules, to start */ module->numprefs = 0; module->prefs_changed = FALSE; module->obsolete = FALSE; @@ -238,7 +253,7 @@ prefs_register_module_or_subtree(module_t *parent, const char *name, /* * It goes into the list for this module. */ - parent->prefs = g_list_insert_sorted(parent->prefs, module, + parent->submodules = g_list_insert_sorted(parent->submodules, module, module_compare_title); } @@ -271,6 +286,59 @@ prefs_register_protocol(int id, void (*apply_cb)(void)) proto_get_protocol_name(id), apply_cb); } + +module_t * +prefs_register_protocol_subtree(const char *subtree, int id, void (*apply_cb)(void)) +{ + protocol_t *protocol; + module_t *subtree_module; + module_t *new_module; + char *sep = NULL, *ptr = NULL; + char *csubtree = NULL; + + /* + * Have we yet created the "Protocols" subtree? + */ + if (protocols_module == NULL) { + /* + * No. Do so. + */ + protocols_module = prefs_register_subtree(NULL, "Protocols", NULL); + } + + subtree_module = protocols_module; + + if(subtree) { + /* take a copy of the buffer */ + ptr = csubtree = g_strdup(subtree); + + while(ptr && *ptr) { + + if((sep = strchr(ptr, '/'))) + *sep++ = '\0'; + + if(!(new_module = find_subtree(subtree_module, ptr))) { + /* create it */ + new_module = prefs_register_subtree(subtree_module, ptr, NULL); + } + + subtree_module = new_module; + ptr = sep; + + } + + /* g_free(csubtree); */ + + } + + protocol = find_protocol_by_id(id); + return prefs_register_module(subtree_module, + proto_get_protocol_filter_name(id), + proto_get_protocol_short_name(protocol), + proto_get_protocol_name(id), apply_cb); +} + + /* * Register that a protocol used to have preferences but no longer does, * by creating an "obsolete" module for it. @@ -322,6 +390,27 @@ prefs_find_module(const char *name) return (module_t *) list_entry->data; } +static gint +subtree_match(gconstpointer a, gconstpointer b) +{ + const module_t *module = a; + const char *title = b; + + return strcmp(title, module->title); +} + +static module_t * +find_subtree(module_t *parent, const char *name) +{ + GList *list_entry; + + list_entry = g_list_find_custom(parent ? parent->submodules : top_level_modules, + name, subtree_match); + if (list_entry == NULL) + return NULL; /* no such module */ + return (module_t *) list_entry->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 @@ -1306,13 +1395,7 @@ read_prefs_file(const char *pf_path, FILE *pf, pref_set_pair_cb pref_set_pair_fc } break; case IN_VAL: - if (got_c != '#') { - g_string_append_c(cur_val, (gchar) got_c); - } else { - while (isspace((guchar)cur_val->str[cur_val->len]) && cur_val->len > 0) - g_string_truncate(cur_val, cur_val->len - 1); - state = IN_SKIP; - } + g_string_append_c(cur_val, (gchar) got_c); break; } } diff --git a/epan/prefs.h b/epan/prefs.h index 52e1adeff0..230361eea1 100644 --- a/epan/prefs.h +++ b/epan/prefs.h @@ -195,6 +195,14 @@ extern module_t *prefs_register_subtree(module_t *parent, const char *title, extern module_t *prefs_register_protocol(int id, void (*apply_cb)(void)); /* + * Register that a protocol has preferences and group it under a single + * subtree + */ +#define PREFERENCE_GROUPING +extern module_t *prefs_register_protocol_subtree(const char *subtree, int id, + void (*apply_cb)(void)); + +/* * Register that a protocol used to have preferences but no longer does, * by creating an "obsolete" module for it. */ diff --git a/gtk/prefs_dlg.c b/gtk/prefs_dlg.c index da16a45ed5..55e2a1e60a 100644 --- a/gtk/prefs_dlg.c +++ b/gtk/prefs_dlg.c @@ -127,6 +127,8 @@ struct ct_struct { gboolean is_protocol; }; +static gint blank_page = 0; + static guint pref_exists(pref_t *pref _U_, gpointer user_data _U_) { @@ -277,7 +279,7 @@ module_prefs_show(module_t *module, gpointer user_data) /* * Is this module a subtree, with modules underneath it? */ - if (!module->is_subtree) { + if (!module->submodules) { /* * No. * Does it have any preferences (other than possibly obsolete ones)? @@ -299,25 +301,24 @@ module_prefs_show(module_t *module, gpointer user_data) 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, !module->is_subtree, + &label_ptr, 5, NULL, NULL, NULL, NULL, !module->submodules, FALSE); #else model = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(cts->tree))); - if (module->is_subtree) - gtk_tree_store_append(model, &iter, NULL); - else - gtk_tree_store_append(model, &iter, &cts->iter); + if (module->submodules && !cts->iter.stamp) + gtk_tree_store_append(model, &iter, NULL); + else + gtk_tree_store_append(model, &iter, &cts->iter); #endif /* * Is this a subtree? */ - if (module->is_subtree) { + if (module->submodules) { /* * 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)); @@ -336,10 +337,15 @@ module_prefs_show(module_t *module, gpointer user_data) #endif if (module == protocols_module) child_cts.is_protocol = TRUE; - prefs_module_list_foreach(module->prefs, module_prefs_show, &child_cts); - } else { + prefs_module_list_foreach(module->submodules, module_prefs_show, &child_cts); + + /* keep the page count right */ + cts->page = child_cts.page; + + } + if(module->prefs) { /* - * No. Create a notebook page for it. + * Has preferences. Create a notebook page for it. */ /* Scrolled window */ @@ -383,10 +389,21 @@ module_prefs_show(module_t *module, gpointer user_data) OBJECT_SET_DATA(frame, E_PAGE_ITER_KEY, gtk_tree_iter_copy(&iter)); #endif - cts->page++; + cts->page++; /* Show 'em what we got */ gtk_widget_show_all(main_sw); + } else { + /* show the blank page */ + +#if GTK_MAJOR_VERSION < 2 + gtk_ctree_node_set_row_data(GTK_CTREE(cts->tree), ct_node, + GINT_TO_POINTER(blank_page)); +#else + gtk_tree_store_set(model, &iter, 0, label_str, 1, blank_page, -1); +#endif + + } return 0; @@ -434,8 +451,10 @@ prefs_nb_page_add(GtkWidget *notebook, const gchar *title, GtkWidget *page, cons frame = gtk_frame_new(title); gtk_widget_show(frame); - gtk_container_add(GTK_CONTAINER(frame), page); - OBJECT_SET_DATA(prefs_w, page_key, page); + if(page) { + gtk_container_add(GTK_CONTAINER(frame), page); + OBJECT_SET_DATA(prefs_w, page_key, page); + } gtk_notebook_append_page (GTK_NOTEBOOK(notebook), frame, NULL); return frame; @@ -518,6 +537,7 @@ prefs_cb(GtkWidget *w _U_, gpointer dummy _U_) #else store = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_INT); cts.tree = tree_view_new(GTK_TREE_MODEL(store)); + cts.iter.stamp = 0; /* mark this as the toplevel */ OBJECT_SET_DATA(prefs_w, E_PREFSW_TREE_KEY, cts.tree); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(cts.tree), FALSE); selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(cts.tree)); @@ -545,6 +565,11 @@ prefs_cb(GtkWidget *w _U_, gpointer dummy _U_) cts.page = 0; + /* Blank Page */ + strcpy(label_str, "(No Specific Preferences)"); + prefs_nb_page_add(prefs_nb, label_str, NULL, NULL); + blank_page = cts.page++; + /* GUI prefs */ strcpy(label_str, "User Interface"); prefs_nb_page_add(prefs_nb, label_str, gui_prefs_show(), E_GUI_PAGE_KEY); @@ -1673,9 +1698,31 @@ module_search_properties(module_t *module, gpointer user_data) p->module = module; return 1; /* stops the search */ } + + if(module->submodules) + return prefs_module_list_foreach(module->submodules, module_search_properties, p); + return 0; } +#if GTK_MAJOR_VERSION >= 2 +static void +tree_expand_row(GtkTreeModel *model, GtkTreeView *tree_view, GtkTreeIter *iter) +{ + GtkTreeIter parent; + GtkTreePath *path; + + /* expand the parent first */ + if(gtk_tree_model_iter_parent(model, &parent, iter)) + tree_expand_row(model, tree_view, &parent); + + path = gtk_tree_model_get_path(model, iter); + gtk_tree_view_expand_row(tree_view, path, FALSE); + /*expand_tree(tree_view, &parent, NULL, NULL);*/ + + gtk_tree_path_free(path); +} +#endif /* select a node in the tree view */ /* XXX - this is almost 100% copied from byte_view_select() in proto_draw.c, @@ -1691,8 +1738,7 @@ tree_select_node(GtkWidget *tree, prefs_tree_iter *iter) GtkTreeIter local_iter = *iter; GtkTreeView *tree_view = GTK_TREE_VIEW(tree); GtkTreeModel *model; - GtkTreePath *first_path, *path; - GtkTreeIter parent; + GtkTreePath *first_path; #endif #if GTK_MAJOR_VERSION < 2 @@ -1718,17 +1764,9 @@ tree_select_node(GtkWidget *tree, prefs_tree_iter *iter) /* Expand our field's row */ first_path = gtk_tree_model_get_path(model, &local_iter); - gtk_tree_view_expand_row(tree_view, first_path, FALSE); - /*expand_tree(tree_view, &iter, NULL, NULL);*/ - /* ... and its parents */ - while (gtk_tree_model_iter_parent(model, &parent, &local_iter)) { - path = gtk_tree_model_get_path(model, &parent); - gtk_tree_view_expand_row(tree_view, path, FALSE); - /*expand_tree(tree_view, &parent, NULL, NULL);*/ - local_iter = parent; - gtk_tree_path_free(path); - } + /* expand from the top down */ + tree_expand_row(model, tree_view, &local_iter); /* select our field's row */ gtk_tree_selection_select_path(gtk_tree_view_get_selection(tree_view), @@ -1774,7 +1812,7 @@ properties_cb(GtkWidget *w, gpointer dummy) XXX - should we just associate protocols with modules directly? */ p.title = title; p.module = NULL; - prefs_module_list_foreach(protocols_module->prefs, module_search_properties, + prefs_module_list_foreach(protocols_module->submodules, module_search_properties, &p); if (p.module == NULL) { /* We didn't find it - that protocol probably has no preferences. */ |