/* * Note that this is called every time the user clicks on an item, * whether it is already selected or not. */ static void field_select_row_cb(GtkTreeSelection *sel, gpointer tree) { GtkWidget *window = (GtkWidget *)gtk_widget_get_toplevel((GtkWidget *)tree); GtkWidget *relation_list = (GtkWidget *)g_object_get_data(G_OBJECT(window), E_DFILTER_EXPR_RELATION_LIST_KEY); GtkWidget *range_label = (GtkWidget *)g_object_get_data(G_OBJECT(window), E_DFILTER_EXPR_RANGE_LABEL_KEY); GtkWidget *range_entry = (GtkWidget *)g_object_get_data(G_OBJECT(window), E_DFILTER_EXPR_RANGE_ENTRY_KEY); GtkWidget *value_label = (GtkWidget *)g_object_get_data(G_OBJECT(window), E_DFILTER_EXPR_VALUE_LABEL_KEY); GtkWidget *value_entry = (GtkWidget *)g_object_get_data(G_OBJECT(window), E_DFILTER_EXPR_VALUE_ENTRY_KEY); GtkWidget *value_list_label = (GtkWidget *)g_object_get_data(G_OBJECT(window), E_DFILTER_EXPR_VALUE_LIST_LABEL_KEY); GtkWidget *value_list = (GtkWidget *)g_object_get_data(G_OBJECT(window), E_DFILTER_EXPR_VALUE_LIST_KEY); GtkWidget *value_list_scrolled_win = (GtkWidget *)g_object_get_data(G_OBJECT(window), E_DFILTER_EXPR_VALUE_LIST_SW_KEY); GtkWidget *ok_bt = (GtkWidget *)g_object_get_data(G_OBJECT(window), E_DFILTER_EXPR_OK_BT_KEY); header_field_info *hfinfo, *cur_hfinfo; const char *value_type; char value_label_string[1024+1]; /* XXX - should be large enough */ GtkTreeModel *model; GtkTreeIter iter; if (!gtk_tree_selection_get_selected(sel, &model, &iter)) return; gtk_tree_model_get(model, &iter, 0, &hfinfo, -1); /* * What was the item that was last selected? */ cur_hfinfo = (header_field_info *)g_object_get_data(G_OBJECT(window), E_DFILTER_EXPR_CURRENT_VAR_KEY); if (cur_hfinfo == hfinfo) { /* * It's still selected; no need to change anything. */ return; } /* * Mark it as currently selected. */ g_object_set_data(G_OBJECT(window), E_DFILTER_EXPR_CURRENT_VAR_KEY, hfinfo); show_relations(relation_list, hfinfo->type); /* * Set the label for the value to indicate what type of value * it is. */ value_type = ftype_pretty_name(hfinfo->type); if (value_type != NULL) { /* * Indicate what type of value it is. */ g_snprintf(value_label_string, sizeof value_label_string, "Value (%s)", value_type); gtk_label_set_text(GTK_LABEL(value_label), value_label_string); } /* * Clear the entry widget for the value, as whatever * was there before doesn't apply. */ gtk_entry_set_text(GTK_ENTRY(value_entry), ""); switch (hfinfo->type) { case FT_BOOLEAN: /* * The list of values should be the strings for "true" * and "false"; show them in the value list. */ build_boolean_values(value_list_scrolled_win, value_list, (const true_false_string *)hfinfo->strings); break; case FT_UINT8: case FT_UINT16: case FT_UINT24: case FT_UINT32: case FT_INT8: case FT_INT16: case FT_INT24: case FT_INT32: /* * If this has a value_string table (not a range_string table) associated with it, * fill up the list of values, otherwise clear the list of values. */ /* XXX: ToDo: Implement "range-string" filter ? */ if ((hfinfo->strings != NULL) && ! (hfinfo->display & BASE_RANGE_STRING) && ! (hfinfo->display & BASE_VAL64_STRING) && ! ((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM)) { const value_string *vals = (const value_string *)hfinfo->strings; if (hfinfo->display & BASE_EXT_STRING) vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)vals); build_enum_values(value_list_scrolled_win, value_list, vals); } else gtk_list_store_clear(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(value_list)))); break; default: /* * Clear the list of values. */ gtk_list_store_clear(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(value_list)))); break; } /* * Display various items for the value, as appropriate. * The relation we start out with is never a comparison. */ display_value_fields(hfinfo, FALSE, value_label, value_entry, value_list_label, value_list, value_list_scrolled_win, range_label, range_entry); /* * XXX - in browse mode, there always has to be something * selected, so this should always be sensitive. */ gtk_widget_set_sensitive(ok_bt, TRUE); }
/* Try to make an fvalue from a string using a value_string or true_false_string. * This works only for ftypes that are integers. Returns the created fvalue_t* * or NULL if impossible. */ static fvalue_t* mk_fvalue_from_val_string(header_field_info *hfinfo, char *s) { static const true_false_string default_tf = { "True", "False" }; const true_false_string *tf = &default_tf; /* Early return? */ switch(hfinfo->type) { case FT_NONE: case FT_PROTOCOL: case FT_FLOAT: case FT_DOUBLE: case FT_ABSOLUTE_TIME: case FT_RELATIVE_TIME: case FT_IPv4: case FT_IPv6: case FT_IPXNET: case FT_ETHER: case FT_BYTES: case FT_UINT_BYTES: case FT_STRING: case FT_STRINGZ: case FT_UINT_STRING: case FT_UINT64: case FT_INT64: case FT_EUI64: case FT_PCRE: case FT_GUID: case FT_OID: return NULL; case FT_BOOLEAN: case FT_FRAMENUM: case FT_UINT8: case FT_UINT16: case FT_UINT24: case FT_UINT32: case FT_INT8: case FT_INT16: case FT_INT24: case FT_INT32: break; case FT_NUM_TYPES: g_assert_not_reached(); } /* TRUE/FALSE *always* exist for FT_BOOLEAN. */ if (hfinfo->type == FT_BOOLEAN) { if (hfinfo->strings) { tf = hfinfo->strings; } if (g_ascii_strcasecmp(s, tf->true_string) == 0) { return mk_uint32_fvalue(TRUE); } else if (g_ascii_strcasecmp(s, tf->false_string) == 0) { return mk_uint32_fvalue(FALSE); } else { dfilter_error_msg = NULL; /* Prefer this error message */ dfilter_fail("\"%s\" cannot be found among the possible values for %s.", s, hfinfo->abbrev); return NULL; } } /* Do val_strings exist? */ if (!hfinfo->strings) { dfilter_fail("%s cannot accept strings as values.", hfinfo->abbrev); return NULL; } /* Reset the dfilter error message, since *something* interesting * will happen, and the error message will be more interesting than * any error message I happen to have now. */ dfilter_error_msg = NULL; if (hfinfo->display & BASE_RANGE_STRING) { dfilter_fail("\"%s\" cannot accept [range] strings as values.", hfinfo->abbrev); } else if (hfinfo->display == BASE_CUSTOM) { /* If a user wants to match against a custom string, we would * somehow have to have the integer value here to pass it in * to the custom-display function. But we don't have an * integer, we have the string they're trying to match. * -><- */ dfilter_fail("\"%s\" cannot accept [custom] strings as values.", hfinfo->abbrev); } else { const value_string *vals = hfinfo->strings; if (hfinfo->display & BASE_EXT_STRING) vals = VALUE_STRING_EXT_VS_P((value_string_ext *) vals); while (vals->strptr != NULL) { if (g_ascii_strcasecmp(s, vals->strptr) == 0) { return mk_uint32_fvalue(vals->value); } vals++; } dfilter_fail("\"%s\" cannot be found among the possible values for %s.", s, hfinfo->abbrev); } return NULL; }