forked from osmocom/wireshark
Modify multicheck to accept parent parameter.
This makes it possible for multicheck to become a tree-like structure. Example: arg {number=4}{call=--devices}{display=Devices}{tooltip=Device selector}{type=multicheck} value {arg=4}{value=dev1}{display=Parent Device}{enabled=t}{default=t} value {arg=4}{value=dev2}{display=Child Device}{parent=dev1}{enabled=t} value {arg=4}{value=dev3}{display=Another Parent Device}{enabled=t} value {arg=4}{value=dev4}{display=Non-clickable Child Device}{parent=dev3} value {arg=4}{value=dev5}{display=Non-clickable Child of Child}{parent=dev4} Change-Id: I59dd7208ca0ec90cccfc49ae049559cdc6c69a4b Reviewed-on: https://code.wireshark.org/review/4192 Petri-Dish: Pascal Quantin <pascal.quantin@gmail.com> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Roland Knall <rknall@gmail.com> Reviewed-by: Pascal Quantin <pascal.quantin@gmail.com>
This commit is contained in:
parent
0784451200
commit
9c1225f735
|
@ -342,6 +342,8 @@ extcap_token_sentence *extcap_tokenize_sentence(const gchar *s) {
|
|||
tv->param_type = EXTCAP_PARAM_NAME;
|
||||
} else if (g_ascii_strcasecmp(tv->arg, "enabled") == 0) {
|
||||
tv->param_type = EXTCAP_PARAM_ENABLED;
|
||||
} else if (g_ascii_strcasecmp(tv->arg, "parent") == 0) {
|
||||
tv->param_type = EXTCAP_PARAM_PARENT;
|
||||
} else {
|
||||
tv->param_type = EXTCAP_PARAM_UNKNOWN;
|
||||
}
|
||||
|
@ -681,6 +683,7 @@ extcap_arg *extcap_parse_arg_sentence(GList * args, extcap_token_sentence *s) {
|
|||
value->enabled = FALSE;
|
||||
value->is_default = FALSE;
|
||||
value->arg_num = tint;
|
||||
value->parent = NULL;
|
||||
|
||||
if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_VALUE))
|
||||
== NULL) {
|
||||
|
@ -698,6 +701,11 @@ extcap_arg *extcap_parse_arg_sentence(GList * args, extcap_token_sentence *s) {
|
|||
}
|
||||
value->display = g_strdup(v->value);
|
||||
|
||||
if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_PARENT))
|
||||
!= NULL) {
|
||||
value->parent = g_strdup(v->value);
|
||||
}
|
||||
|
||||
if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_DEFAULT))
|
||||
!= NULL) {
|
||||
/* printf("found default value\n"); */
|
||||
|
|
|
@ -67,7 +67,8 @@ typedef enum {
|
|||
EXTCAP_PARAM_TOOLTIP,
|
||||
EXTCAP_PARAM_NAME,
|
||||
EXTCAP_PARAM_ENABLED,
|
||||
EXTCAP_PARAM_FILE_MUSTEXIST
|
||||
EXTCAP_PARAM_FILE_MUSTEXIST,
|
||||
EXTCAP_PARAM_PARENT
|
||||
} extcap_param_type;
|
||||
|
||||
/* Values for a given sentence; values are all stored as a call
|
||||
|
@ -80,6 +81,7 @@ typedef struct _extcap_value {
|
|||
gchar *display;
|
||||
gboolean enabled;
|
||||
gboolean is_default;
|
||||
gchar *parent;
|
||||
} extcap_value;
|
||||
|
||||
/* Complex-ish struct for storing complex values */
|
||||
|
|
|
@ -33,6 +33,87 @@
|
|||
#include <extcap_parser.h>
|
||||
#include "extcap_gtk.h"
|
||||
|
||||
#include "log.h"
|
||||
|
||||
static gboolean extcap_gtk_count_tree_elements(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
|
||||
{
|
||||
int *ptr_count = (int*)data;
|
||||
gboolean multi_enabled;
|
||||
(void)path;
|
||||
|
||||
g_assert(ptr_count != NULL);
|
||||
|
||||
gtk_tree_model_get(model, iter,
|
||||
EXTCAP_GTK_MULTI_COL_CHECK, &multi_enabled, -1);
|
||||
|
||||
if (multi_enabled)
|
||||
{
|
||||
++(*ptr_count);
|
||||
}
|
||||
|
||||
return FALSE; /* Continue iteration. */
|
||||
}
|
||||
|
||||
typedef struct _extcap_gtk_multi_fill_cb_data
|
||||
{
|
||||
gchar **list;
|
||||
int num;
|
||||
int max;
|
||||
} extcap_gtk_multi_fill_cb_data;
|
||||
|
||||
static gboolean extcap_gtk_fill_multi_list(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
|
||||
{
|
||||
extcap_gtk_multi_fill_cb_data *ptr_data = (extcap_gtk_multi_fill_cb_data*)data;
|
||||
gboolean multi_enabled;
|
||||
extcap_value *value;
|
||||
(void)path;
|
||||
|
||||
g_assert(ptr_data != NULL);
|
||||
|
||||
gtk_tree_model_get(model, iter,
|
||||
EXTCAP_GTK_MULTI_COL_CHECK, &multi_enabled,
|
||||
EXTCAP_GTK_MULTI_COL_VALUE, &value, -1);
|
||||
|
||||
if (multi_enabled)
|
||||
{
|
||||
g_assert(ptr_data->num < ptr_data->max);
|
||||
|
||||
if (ptr_data->num < ptr_data->max)
|
||||
{
|
||||
ptr_data->list[ptr_data->num] = g_strdup(value->call);
|
||||
ptr_data->num++;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE; /* Continue iteration. */
|
||||
}
|
||||
|
||||
typedef struct _extcap_gtk_multi_find_cb_data
|
||||
{
|
||||
gchar *parent;
|
||||
GtkTreeIter *parent_iter;
|
||||
} extcap_gtk_multi_find_cb_data;
|
||||
|
||||
static gboolean extcap_gtk_find_parent_in_multi_list(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
|
||||
{
|
||||
extcap_gtk_multi_find_cb_data *ptr_data = (extcap_gtk_multi_find_cb_data*)data;
|
||||
extcap_value *value;
|
||||
(void)path;
|
||||
|
||||
g_assert(ptr_data != NULL);
|
||||
|
||||
gtk_tree_model_get(model, iter,
|
||||
EXTCAP_GTK_MULTI_COL_VALUE, &value, -1);
|
||||
|
||||
if (0 == g_strcmp0(ptr_data->parent, value->call))
|
||||
{
|
||||
ptr_data->parent_iter = gtk_tree_iter_copy(iter);
|
||||
return TRUE; /* Stop iteration. */
|
||||
}
|
||||
|
||||
return FALSE; /* Continue iteration. */
|
||||
}
|
||||
|
||||
GHashTable *extcap_gtk_get_state(GtkWidget *widget) {
|
||||
GSList *widget_list, *widget_iter;
|
||||
GSList *radio_list = NULL, *radio_iter = NULL;
|
||||
|
@ -51,9 +132,9 @@ GHashTable *extcap_gtk_get_state(GtkWidget *widget) {
|
|||
|
||||
gchar *call_string = NULL;
|
||||
|
||||
gchar **multi_list = NULL;
|
||||
extcap_gtk_multi_fill_cb_data multi_data = { NULL, 0, 0 };
|
||||
|
||||
int multi_num = 0;
|
||||
gboolean multi_valid, multi_enabled;
|
||||
|
||||
widget_list = (GSList *) g_object_get_data(G_OBJECT(widget),
|
||||
EXTCAP_GTK_DATA_KEY_WIDGETLIST);
|
||||
|
@ -173,40 +254,32 @@ GHashTable *extcap_gtk_get_state(GtkWidget *widget) {
|
|||
multi_num = 0;
|
||||
|
||||
/* Count the # of items enabled */
|
||||
multi_valid = gtk_tree_model_get_iter_first(treemodel, &treeiter);
|
||||
while (multi_valid) {
|
||||
gtk_tree_model_get(treemodel, &treeiter,
|
||||
EXTCAP_GTK_MULTI_COL_CHECK, &multi_enabled, -1);
|
||||
gtk_tree_model_foreach(treemodel, extcap_gtk_count_tree_elements,
|
||||
&multi_num);
|
||||
|
||||
if (multi_enabled)
|
||||
multi_num++;
|
||||
|
||||
multi_valid = gtk_tree_model_iter_next(treemodel, &treeiter);
|
||||
}
|
||||
|
||||
multi_list = g_new(gchar *, multi_num + 1);
|
||||
if (multi_num > 0)
|
||||
{
|
||||
multi_data.list = g_new(gchar *, multi_num + 1);
|
||||
multi_data.num = 0;
|
||||
multi_data.max = multi_num;
|
||||
|
||||
multi_num = 0;
|
||||
|
||||
/* Count the # of items enabled */
|
||||
multi_valid = gtk_tree_model_get_iter_first(treemodel, &treeiter);
|
||||
while (multi_valid) {
|
||||
gtk_tree_model_get(treemodel, &treeiter,
|
||||
EXTCAP_GTK_MULTI_COL_CHECK, &multi_enabled,
|
||||
EXTCAP_GTK_MULTI_COL_VALUE, &value, -1);
|
||||
/* Get values list of items enabled */
|
||||
gtk_tree_model_foreach(treemodel, extcap_gtk_fill_multi_list,
|
||||
&multi_data);
|
||||
|
||||
if (multi_enabled) {
|
||||
multi_list[multi_num] = g_strdup(value->call);
|
||||
multi_num++;
|
||||
multi_data.list[multi_data.max] = NULL;
|
||||
|
||||
call_string = g_strjoinv(",", multi_data.list);
|
||||
|
||||
g_strfreev(multi_data.list);
|
||||
}
|
||||
|
||||
multi_valid = gtk_tree_model_iter_next(treemodel, &treeiter);
|
||||
else
|
||||
{
|
||||
/* There are no enabled items. Skip this argument from command line. */
|
||||
continue;
|
||||
}
|
||||
multi_list[multi_num] = NULL;
|
||||
|
||||
call_string = g_strjoinv(",", multi_list);
|
||||
|
||||
g_strfreev(multi_list);
|
||||
|
||||
break;
|
||||
default:
|
||||
|
@ -422,7 +495,7 @@ static void extcap_gtk_multicheck_toggled(GtkCellRendererToggle *cell _U_,
|
|||
|
||||
enabled ^= 1;
|
||||
|
||||
gtk_list_store_set(GTK_LIST_STORE(model), &iter, EXTCAP_GTK_MULTI_COL_CHECK,
|
||||
gtk_tree_store_set(GTK_TREE_STORE(model), &iter, EXTCAP_GTK_MULTI_COL_CHECK,
|
||||
enabled, -1);
|
||||
|
||||
gtk_tree_path_free(path);
|
||||
|
@ -541,7 +614,7 @@ GtkWidget *extcap_create_gtk_multicheckwidget(extcap_arg *argument,
|
|||
GtkCellRenderer *renderer, *togglerenderer;
|
||||
GtkTreeModel *model;
|
||||
GtkWidget *view, *retview;
|
||||
GtkListStore *store;
|
||||
GtkTreeStore *store;
|
||||
GtkTreeIter iter;
|
||||
GtkTreeSelection *selection;
|
||||
extcap_value *v = NULL;
|
||||
|
@ -549,6 +622,7 @@ GtkWidget *extcap_create_gtk_multicheckwidget(extcap_arg *argument,
|
|||
gchar *prev_item = NULL;
|
||||
gchar **prev_list = NULL, **prev_iter = NULL;
|
||||
gboolean prev_value, prev_matched;
|
||||
extcap_gtk_multi_find_cb_data find_data;
|
||||
|
||||
if (g_list_length(argument->values) == 0)
|
||||
return NULL ;
|
||||
|
@ -557,8 +631,8 @@ GtkWidget *extcap_create_gtk_multicheckwidget(extcap_arg *argument,
|
|||
|
||||
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
|
||||
|
||||
store = gtk_list_store_new(EXTCAP_GTK_MULTI_NUM_COLS, G_TYPE_BOOLEAN,
|
||||
G_TYPE_STRING, G_TYPE_POINTER);
|
||||
store = gtk_tree_store_new(EXTCAP_GTK_MULTI_NUM_COLS, G_TYPE_BOOLEAN,
|
||||
G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_BOOLEAN);
|
||||
|
||||
model = GTK_TREE_MODEL(store);
|
||||
gtk_tree_view_set_model(GTK_TREE_VIEW(view), model);
|
||||
|
@ -576,9 +650,30 @@ GtkWidget *extcap_create_gtk_multicheckwidget(extcap_arg *argument,
|
|||
if (v->display == NULL)
|
||||
break;
|
||||
|
||||
find_data.parent = v->parent;
|
||||
find_data.parent_iter = NULL;
|
||||
|
||||
if (find_data.parent != NULL)
|
||||
{
|
||||
gtk_tree_model_foreach(model, extcap_gtk_find_parent_in_multi_list,
|
||||
&find_data);
|
||||
if (find_data.parent_iter == NULL)
|
||||
{
|
||||
g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
|
||||
"Extcap parent %s not found for value %s (%s)",
|
||||
v->parent, v->call, argument->call);
|
||||
}
|
||||
}
|
||||
|
||||
prev_value = FALSE;
|
||||
prev_matched = FALSE;
|
||||
gtk_list_store_append(store, &iter);
|
||||
gtk_tree_store_append(store, &iter, find_data.parent_iter);
|
||||
|
||||
if (find_data.parent_iter != NULL)
|
||||
{
|
||||
gtk_tree_iter_free(find_data.parent_iter);
|
||||
find_data.parent_iter = NULL;
|
||||
}
|
||||
|
||||
if (prev_list != NULL) {
|
||||
prev_matched = FALSE;
|
||||
|
@ -593,14 +688,23 @@ GtkWidget *extcap_create_gtk_multicheckwidget(extcap_arg *argument,
|
|||
|
||||
prev_iter++;
|
||||
}
|
||||
}
|
||||
|
||||
if (prev_matched == FALSE)
|
||||
prev_value = v->enabled;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Use default value if there is no information about previously selected items. */
|
||||
prev_value = v->is_default;
|
||||
}
|
||||
|
||||
gtk_list_store_set(store, &iter, EXTCAP_GTK_MULTI_COL_CHECK, prev_value,
|
||||
|
||||
/* v->is_default is set when there was {default=true} for this value. */
|
||||
/* v->enabled is false for non-clickable tree items ({enabled=false}). */
|
||||
gtk_tree_store_set(store, &iter, EXTCAP_GTK_MULTI_COL_CHECK, prev_value,
|
||||
EXTCAP_GTK_MULTI_COL_DISPLAY, v->display,
|
||||
EXTCAP_GTK_MULTI_COL_VALUE, v, -1);
|
||||
EXTCAP_GTK_MULTI_COL_VALUE, v,
|
||||
EXTCAP_GTK_MULTI_COL_ACTIVATABLE, v->enabled, -1);
|
||||
}
|
||||
|
||||
if (prev_list != NULL)
|
||||
|
@ -612,6 +716,8 @@ GtkWidget *extcap_create_gtk_multicheckwidget(extcap_arg *argument,
|
|||
G_CALLBACK(extcap_gtk_multicheck_toggled), model);
|
||||
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view), -1,
|
||||
"Enabled", togglerenderer, "active", EXTCAP_GTK_MULTI_COL_CHECK,
|
||||
"activatable", EXTCAP_GTK_MULTI_COL_ACTIVATABLE,
|
||||
"visible", EXTCAP_GTK_MULTI_COL_ACTIVATABLE,
|
||||
NULL);
|
||||
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view), -1, "Name",
|
||||
renderer, "text", EXTCAP_GTK_MULTI_COL_DISPLAY,
|
||||
|
|
|
@ -79,6 +79,7 @@ enum extcap_gtk_multi_col_types {
|
|||
EXTCAP_GTK_MULTI_COL_CHECK = 0,
|
||||
EXTCAP_GTK_MULTI_COL_DISPLAY = 1,
|
||||
EXTCAP_GTK_MULTI_COL_VALUE = 2,
|
||||
EXTCAP_GTK_MULTI_COL_ACTIVATABLE = 3,
|
||||
EXTCAP_GTK_MULTI_NUM_COLS
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue