Beispiel #1
0
/*
 * 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;
}