summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomasz Moń <desowin@gmail.com>2014-09-19 19:34:07 +0200
committerPascal Quantin <pascal.quantin@gmail.com>2014-10-06 09:51:56 +0000
commit9c1225f73511b59dd74273545fac401d711cea36 (patch)
tree03b12e1443a273cd91e83a66a24f8092a87ce880
parent07844512004aacc0a9ecc01ade01081f59a24c64 (diff)
downloadwireshark-9c1225f73511b59dd74273545fac401d711cea36.tar.gz
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>
-rw-r--r--extcap_parser.c8
-rw-r--r--extcap_parser.h4
-rw-r--r--ui/gtk/extcap_gtk.c182
-rw-r--r--ui/gtk/extcap_gtk.h1
4 files changed, 156 insertions, 39 deletions
diff --git a/extcap_parser.c b/extcap_parser.c
index 29c9b9de9a..3e239702e3 100644
--- a/extcap_parser.c
+++ b/extcap_parser.c
@@ -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"); */
diff --git a/extcap_parser.h b/extcap_parser.h
index 0058597535..4076dec670 100644
--- a/extcap_parser.h
+++ b/extcap_parser.h
@@ -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 */
diff --git a/ui/gtk/extcap_gtk.c b/ui/gtk/extcap_gtk.c
index 69e1393dbd..e3d63c9862 100644
--- a/ui/gtk/extcap_gtk.c
+++ b/ui/gtk/extcap_gtk.c
@@ -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++;
+ if (multi_num > 0)
+ {
+ multi_data.list = g_new(gchar *, multi_num + 1);
+ multi_data.num = 0;
+ multi_data.max = multi_num;
- multi_valid = gtk_tree_model_iter_next(treemodel, &treeiter);
- }
+ multi_num = 0;
- multi_list = g_new(gchar *, multi_num + 1);
+ /* Get values list of items enabled */
+ gtk_tree_model_foreach(treemodel, extcap_gtk_fill_multi_list,
+ &multi_data);
- multi_num = 0;
+ multi_data.list[multi_data.max] = NULL;
- /* 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);
-
- if (multi_enabled) {
- multi_list[multi_num] = g_strdup(value->call);
- multi_num++;
- }
+ call_string = g_strjoinv(",", multi_data.list);
- multi_valid = gtk_tree_model_iter_next(treemodel, &treeiter);
+ g_strfreev(multi_data.list);
+ }
+ 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;
}
- if (prev_matched == FALSE)
- prev_value = v->enabled;
- 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,
diff --git a/ui/gtk/extcap_gtk.h b/ui/gtk/extcap_gtk.h
index 07a8f21e7b..eb49c545f7 100644
--- a/ui/gtk/extcap_gtk.h
+++ b/ui/gtk/extcap_gtk.h
@@ -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
};