Custom model for packet details
Original patch tracked in bug #7224 svn path=/trunk/; revision=43189
This commit is contained in:
parent
a2bb94c3b3
commit
f372010ee8
|
@ -130,6 +130,7 @@ WIRESHARK_GTK_SRC = \
|
|||
proto_help.c \
|
||||
proto_hier_stats_dlg.c \
|
||||
proto_hier_tree_model.c \
|
||||
proto_tree_model.c \
|
||||
range_utils.c \
|
||||
rtp_player.c \
|
||||
rtp_stream.c \
|
||||
|
@ -329,6 +330,7 @@ noinst_HEADERS = \
|
|||
proto_help.h \
|
||||
proto_hier_stats_dlg.h \
|
||||
proto_hier_tree_model.h \
|
||||
proto_tree_model.h \
|
||||
range_utils.h \
|
||||
remote_icons.h \
|
||||
rtp_analysis.h \
|
||||
|
|
|
@ -76,6 +76,7 @@
|
|||
#include "ui/gtk/main.h"
|
||||
#include "ui/gtk/menus.h"
|
||||
#include "ui/gtk/main_proto_draw.h"
|
||||
#include "ui/gtk/proto_tree_model.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <gdk/gdkwin32.h>
|
||||
|
@ -100,9 +101,6 @@ static GtkWidget *
|
|||
add_byte_tab(GtkWidget *byte_nb, const char *name, tvbuff_t *tvb,
|
||||
proto_tree *tree, GtkWidget *tree_view);
|
||||
|
||||
static void
|
||||
proto_tree_draw_node(proto_node *node, gpointer data);
|
||||
|
||||
/* Get the current text window for the notebook. */
|
||||
GtkWidget *
|
||||
get_notebook_bv_ptr(GtkWidget *nb_ptr)
|
||||
|
@ -2006,7 +2004,7 @@ GtkWidget *
|
|||
main_tree_view_new(e_prefs *prefs_p, GtkWidget **tree_view_p)
|
||||
{
|
||||
GtkWidget *tv_scrollw, *tree_view;
|
||||
GtkTreeStore *store;
|
||||
ProtoTreeModel *store;
|
||||
GtkCellRenderer *renderer;
|
||||
GtkTreeViewColumn *column;
|
||||
gint col_offset;
|
||||
|
@ -2016,7 +2014,7 @@ main_tree_view_new(e_prefs *prefs_p, GtkWidget **tree_view_p)
|
|||
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(tv_scrollw),
|
||||
GTK_SHADOW_IN);
|
||||
|
||||
store = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_POINTER);
|
||||
store = proto_tree_model_new(NULL, prefs.display_hidden_proto_items);
|
||||
tree_view = tree_view_new(GTK_TREE_MODEL(store));
|
||||
g_object_unref(G_OBJECT(store));
|
||||
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree_view), FALSE);
|
||||
|
@ -2069,11 +2067,6 @@ collapse_all_tree(proto_tree *protocol_tree _U_, GtkWidget *tree_view)
|
|||
}
|
||||
|
||||
|
||||
struct proto_tree_draw_info {
|
||||
GtkTreeView *tree_view;
|
||||
GtkTreeIter *iter;
|
||||
};
|
||||
|
||||
void
|
||||
main_proto_tree_draw(proto_tree *protocol_tree)
|
||||
{
|
||||
|
@ -2136,103 +2129,37 @@ tree_view_select(GtkWidget *widget, GdkEventButton *event)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
expand_finfos(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
|
||||
{
|
||||
GtkTreeView *tree_view = (GtkTreeView *) data;
|
||||
field_info *fi;
|
||||
|
||||
if (!gtk_tree_model_iter_has_child(model, iter))
|
||||
return FALSE;
|
||||
|
||||
gtk_tree_model_get(model, iter, 1, &fi, -1);
|
||||
|
||||
g_assert(fi->tree_type >= 0 && fi->tree_type < num_tree_types);
|
||||
|
||||
if (tree_is_expanded[fi->tree_type])
|
||||
gtk_tree_view_expand_to_path(tree_view, path);
|
||||
else
|
||||
gtk_tree_view_collapse_row(tree_view, path);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* fill the whole protocol tree with the string values */
|
||||
void
|
||||
proto_tree_draw(proto_tree *protocol_tree, GtkWidget *tree_view)
|
||||
{
|
||||
GtkTreeStore *store;
|
||||
struct proto_tree_draw_info info;
|
||||
ProtoTreeModel *model;
|
||||
|
||||
info.tree_view = GTK_TREE_VIEW(tree_view);
|
||||
info.iter = NULL;
|
||||
model = proto_tree_model_new(protocol_tree, prefs.display_hidden_proto_items);
|
||||
gtk_tree_view_set_model(GTK_TREE_VIEW(tree_view), GTK_TREE_MODEL(model));
|
||||
|
||||
store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(tree_view)));
|
||||
|
||||
/*
|
||||
* Clear out any crud left over in the display of the protocol
|
||||
* tree, by removing all nodes from the tree.
|
||||
* This is how it's done in testgtk.c in GTK+.
|
||||
*/
|
||||
gtk_tree_store_clear(store);
|
||||
|
||||
if (protocol_tree)
|
||||
proto_tree_children_foreach(protocol_tree, proto_tree_draw_node, &info);
|
||||
}
|
||||
|
||||
|
||||
/* fill a single protocol tree item with the string value */
|
||||
static void
|
||||
proto_tree_draw_node(proto_node *node, gpointer data)
|
||||
{
|
||||
struct proto_tree_draw_info info;
|
||||
struct proto_tree_draw_info *parent_info = (struct proto_tree_draw_info*) data;
|
||||
|
||||
field_info *fi = PNODE_FINFO(node);
|
||||
gchar label_str[ITEM_LABEL_LENGTH];
|
||||
gchar *label_ptr;
|
||||
gboolean is_leaf, is_expanded;
|
||||
GtkTreeStore *store;
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path;
|
||||
|
||||
g_assert(fi && "dissection with an invisible proto tree?");
|
||||
|
||||
if (PROTO_ITEM_IS_HIDDEN(node) && !prefs.display_hidden_proto_items)
|
||||
return;
|
||||
|
||||
/* was a free format label produced? */
|
||||
if (fi->rep) {
|
||||
label_ptr = fi->rep->representation;
|
||||
}
|
||||
else { /* no, make a generic label */
|
||||
label_ptr = label_str;
|
||||
proto_item_fill_label(fi, label_str);
|
||||
}
|
||||
|
||||
if (node->first_child != NULL) {
|
||||
is_leaf = FALSE;
|
||||
g_assert(fi->tree_type >= 0 && fi->tree_type < num_tree_types);
|
||||
if (tree_is_expanded[fi->tree_type]) {
|
||||
is_expanded = TRUE;
|
||||
}
|
||||
else {
|
||||
is_expanded = FALSE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
is_leaf = TRUE;
|
||||
is_expanded = FALSE;
|
||||
}
|
||||
|
||||
if (PROTO_ITEM_IS_GENERATED(node)) {
|
||||
if (PROTO_ITEM_IS_HIDDEN(node)) {
|
||||
label_ptr = g_strdup_printf("<[%s]>", label_ptr);
|
||||
} else {
|
||||
label_ptr = g_strdup_printf("[%s]", label_ptr);
|
||||
}
|
||||
} else if (PROTO_ITEM_IS_HIDDEN(node)) {
|
||||
label_ptr = g_strdup_printf("<%s>", label_ptr);
|
||||
}
|
||||
|
||||
info.tree_view = parent_info->tree_view;
|
||||
store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(info.tree_view)));
|
||||
gtk_tree_store_append(store, &iter, parent_info->iter);
|
||||
gtk_tree_store_set(store, &iter, 0, label_ptr, 1, fi, -1);
|
||||
|
||||
if (PROTO_ITEM_IS_GENERATED(node) || PROTO_ITEM_IS_HIDDEN(node)) {
|
||||
g_free(label_ptr);
|
||||
}
|
||||
|
||||
if (!is_leaf) {
|
||||
info.iter = &iter;
|
||||
proto_tree_children_foreach(node, proto_tree_draw_node, &info);
|
||||
path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter);
|
||||
if (is_expanded)
|
||||
gtk_tree_view_expand_to_path(info.tree_view, path);
|
||||
else
|
||||
gtk_tree_view_collapse_row(info.tree_view, path);
|
||||
gtk_tree_path_free(path);
|
||||
}
|
||||
gtk_tree_model_foreach(GTK_TREE_MODEL(model), expand_finfos, GTK_TREE_VIEW(tree_view));
|
||||
g_object_unref(G_OBJECT(model));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -0,0 +1,455 @@
|
|||
/* proto_tree_model.c
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
/* This code was originally based on the GTK+ Tree View tutorial at
|
||||
* http://scentric.net/tutorial */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include <epan/proto.h>
|
||||
|
||||
static GObjectClass *parent_class = NULL;
|
||||
|
||||
typedef struct {
|
||||
GObjectClass parent_class;
|
||||
|
||||
} ProtoTreeModelClass;
|
||||
|
||||
struct proto_tree_model {
|
||||
GObject parent; /** MUST be first */
|
||||
|
||||
/** Random integer to check whether an iter belongs to our model. */
|
||||
gint stamp;
|
||||
|
||||
proto_tree *protocol_tree;
|
||||
int with_hidden;
|
||||
};
|
||||
|
||||
#include "proto_tree_model.h"
|
||||
|
||||
static GtkTreeModelFlags
|
||||
proto_tree_model_get_flags(GtkTreeModel *tree_model)
|
||||
{
|
||||
g_return_val_if_fail(PROTO_IS_TREE(tree_model), (GtkTreeModelFlags)0);
|
||||
|
||||
return GTK_TREE_MODEL_ITERS_PERSIST;
|
||||
}
|
||||
|
||||
static gint
|
||||
proto_tree_model_get_n_columns(GtkTreeModel *tree_model)
|
||||
{
|
||||
g_return_val_if_fail(PROTO_IS_TREE(tree_model), 0);
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
static GType
|
||||
proto_tree_model_get_column_type(GtkTreeModel *tree_model, gint idx)
|
||||
{
|
||||
g_return_val_if_fail(PROTO_IS_TREE(tree_model), G_TYPE_INVALID);
|
||||
g_return_val_if_fail(idx == 0 || idx == 1, G_TYPE_INVALID);
|
||||
|
||||
switch (idx) {
|
||||
case 0:
|
||||
return G_TYPE_STRING;
|
||||
case 1:
|
||||
return G_TYPE_POINTER;
|
||||
}
|
||||
/* never here */
|
||||
return G_TYPE_INVALID;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
proto_tree_model_iter_nth_child(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent, gint n)
|
||||
{
|
||||
ProtoTreeModel *model;
|
||||
proto_node *node;
|
||||
|
||||
g_return_val_if_fail(PROTO_IS_TREE(tree_model), FALSE);
|
||||
model = (ProtoTreeModel *) tree_model;
|
||||
|
||||
if (parent) {
|
||||
g_return_val_if_fail(parent->stamp == model->stamp, FALSE);
|
||||
node = parent->user_data;
|
||||
} else
|
||||
node = model->protocol_tree;
|
||||
|
||||
if (!node)
|
||||
return FALSE;
|
||||
|
||||
node = node->first_child;
|
||||
while (node != NULL) {
|
||||
if (model->with_hidden || !PROTO_ITEM_IS_HIDDEN(node)) {
|
||||
if (!n)
|
||||
break;
|
||||
n--;
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
/* not found? */
|
||||
if (!node)
|
||||
return FALSE;
|
||||
|
||||
iter->stamp = model->stamp;
|
||||
iter->user_data = node;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
proto_tree_model_get_iter(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreePath *path)
|
||||
{
|
||||
gint *indices, depth;
|
||||
|
||||
g_assert(PROTO_IS_TREE(tree_model));
|
||||
g_assert(path != NULL);
|
||||
|
||||
indices = gtk_tree_path_get_indices(path);
|
||||
depth = gtk_tree_path_get_depth(path);
|
||||
|
||||
g_return_val_if_fail(depth > 0, FALSE);
|
||||
|
||||
if (!proto_tree_model_iter_nth_child(tree_model, iter, NULL, indices[0]))
|
||||
return FALSE;
|
||||
|
||||
while (--depth) {
|
||||
indices++;
|
||||
if (!proto_tree_model_iter_nth_child(tree_model, iter, iter, *indices))
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static char *
|
||||
fi_get_string(field_info *fi)
|
||||
{
|
||||
gchar label_str[ITEM_LABEL_LENGTH];
|
||||
gchar *label_ptr;
|
||||
|
||||
if (!fi->rep) {
|
||||
label_ptr = label_str;
|
||||
proto_item_fill_label(fi, label_str);
|
||||
} else
|
||||
label_ptr = fi->rep->representation;
|
||||
|
||||
if (FI_GET_FLAG(fi, FI_GENERATED)) {
|
||||
if (FI_GET_FLAG(fi, FI_HIDDEN))
|
||||
label_ptr = g_strdup_printf("<[%s]>", label_ptr);
|
||||
else
|
||||
label_ptr = g_strdup_printf("[%s]", label_ptr);
|
||||
|
||||
} else if (FI_GET_FLAG(fi, FI_HIDDEN))
|
||||
label_ptr = g_strdup_printf("<%s>", label_ptr);
|
||||
else
|
||||
label_ptr = g_strdup(label_ptr);
|
||||
|
||||
return label_ptr;
|
||||
}
|
||||
|
||||
static void
|
||||
proto_tree_model_get_value(GtkTreeModel *tree_model, GtkTreeIter *iter, gint column, GValue *value)
|
||||
{
|
||||
ProtoTreeModel *model;
|
||||
proto_node *node;
|
||||
field_info *fi;
|
||||
|
||||
g_return_if_fail(PROTO_IS_TREE(tree_model));
|
||||
model = (ProtoTreeModel *) tree_model;
|
||||
|
||||
g_return_if_fail(iter != NULL);
|
||||
g_return_if_fail(iter->stamp == model->stamp);
|
||||
g_return_if_fail(column == 0 || column == 1);
|
||||
|
||||
node = iter->user_data;
|
||||
fi = PNODE_FINFO(node);
|
||||
|
||||
g_assert(fi && "dissection with an invisible proto tree?");
|
||||
|
||||
switch (column) {
|
||||
case 0:
|
||||
g_value_init(value, G_TYPE_STRING);
|
||||
g_value_take_string(value, fi_get_string(fi));
|
||||
break;
|
||||
|
||||
case 1:
|
||||
g_value_init(value, G_TYPE_POINTER);
|
||||
g_value_set_pointer(value, fi);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
proto_tree_model_iter_next(GtkTreeModel *tree_model, GtkTreeIter *iter)
|
||||
{
|
||||
ProtoTreeModel *model;
|
||||
proto_node *current;
|
||||
|
||||
g_return_val_if_fail(PROTO_IS_TREE(tree_model), FALSE);
|
||||
model = (ProtoTreeModel *) tree_model;
|
||||
|
||||
g_return_val_if_fail(iter->stamp == model->stamp, FALSE);
|
||||
|
||||
current = iter->user_data;
|
||||
current = current->next;
|
||||
while (current) {
|
||||
if (model->with_hidden || !PROTO_ITEM_IS_HIDDEN(current)) {
|
||||
iter->user_data = current;
|
||||
return TRUE;
|
||||
}
|
||||
current = current->next;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
proto_tree_model_iter_children(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent)
|
||||
{
|
||||
return proto_tree_model_iter_nth_child(tree_model, iter, parent, 0);
|
||||
}
|
||||
|
||||
static gint
|
||||
proto_tree_model_iter_n_children(GtkTreeModel *tree_model, GtkTreeIter *iter)
|
||||
{
|
||||
ProtoTreeModel *model;
|
||||
proto_node *node;
|
||||
gint count;
|
||||
|
||||
g_return_val_if_fail(PROTO_IS_TREE(tree_model), 0);
|
||||
model = (ProtoTreeModel *) tree_model;
|
||||
|
||||
g_return_val_if_fail(iter == NULL || iter->user_data != NULL, 0);
|
||||
|
||||
if (iter) {
|
||||
g_return_val_if_fail(iter->stamp == model->stamp, 0);
|
||||
node = iter->user_data;
|
||||
} else
|
||||
node = model->protocol_tree;
|
||||
|
||||
if (!node)
|
||||
return 0;
|
||||
|
||||
count = 0;
|
||||
node = node->first_child;
|
||||
while (node != NULL) {
|
||||
if (model->with_hidden || !PROTO_ITEM_IS_HIDDEN(node))
|
||||
count++;
|
||||
node = node->next;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static GtkTreePath *
|
||||
proto_tree_model_get_path(GtkTreeModel *tree_model, GtkTreeIter *iter)
|
||||
{
|
||||
ProtoTreeModel *model;
|
||||
GtkTreePath *path;
|
||||
proto_node *node;
|
||||
|
||||
g_return_val_if_fail(PROTO_IS_TREE(tree_model), NULL);
|
||||
model = (ProtoTreeModel *) tree_model;
|
||||
|
||||
g_return_val_if_fail(iter != NULL, NULL);
|
||||
g_return_val_if_fail(iter->stamp == model->stamp, NULL);
|
||||
|
||||
node = iter->user_data;
|
||||
g_return_val_if_fail(node != model->protocol_tree, NULL);
|
||||
|
||||
path = gtk_tree_path_new();
|
||||
do {
|
||||
proto_node *cur = node;
|
||||
proto_node *node_i;
|
||||
int pos;
|
||||
|
||||
node = node->parent;
|
||||
|
||||
pos = 0;
|
||||
for (node_i = node->first_child; node_i; node_i = node_i->next) {
|
||||
if (model->with_hidden || !PROTO_ITEM_IS_HIDDEN(node_i)) {
|
||||
if (node_i == cur)
|
||||
break;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
g_assert(node_i != NULL);
|
||||
gtk_tree_path_prepend_index(path, pos);
|
||||
} while (node != model->protocol_tree);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
proto_tree_model_iter_has_child(GtkTreeModel *tree_model, GtkTreeIter *iter)
|
||||
{
|
||||
/* optimized version of:
|
||||
* return proto_tree_model_iter_n_children(tree_model, iter) != 0;
|
||||
* synchronize when changed!
|
||||
*/
|
||||
ProtoTreeModel *model;
|
||||
proto_node *node;
|
||||
|
||||
g_return_val_if_fail(PROTO_IS_TREE(tree_model), FALSE);
|
||||
model = (ProtoTreeModel *) tree_model;
|
||||
|
||||
g_return_val_if_fail(iter == NULL || iter->user_data != NULL, FALSE);
|
||||
|
||||
if (iter) {
|
||||
g_return_val_if_fail(iter->stamp == model->stamp, FALSE);
|
||||
node = iter->user_data;
|
||||
} else
|
||||
node = model->protocol_tree;
|
||||
|
||||
if (!node)
|
||||
return FALSE;
|
||||
|
||||
node = node->first_child;
|
||||
while (node != NULL) {
|
||||
if (model->with_hidden || !PROTO_ITEM_IS_HIDDEN(node))
|
||||
return TRUE;
|
||||
node = node->next;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
proto_tree_model_iter_parent(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *child)
|
||||
{
|
||||
ProtoTreeModel *model;
|
||||
proto_node *node;
|
||||
|
||||
g_return_val_if_fail(PROTO_IS_TREE(tree_model), FALSE);
|
||||
model = (ProtoTreeModel *) tree_model;
|
||||
|
||||
g_return_val_if_fail(iter != NULL, FALSE);
|
||||
g_return_val_if_fail(child->stamp == model->stamp, FALSE);
|
||||
|
||||
node = child->user_data;
|
||||
if (node->parent == model->protocol_tree)
|
||||
return FALSE;
|
||||
g_return_val_if_fail(node->parent != NULL, FALSE);
|
||||
iter->stamp = model->stamp;
|
||||
iter->user_data = node->parent;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
proto_tree_model_tree_init(GtkTreeModelIface *iface)
|
||||
{
|
||||
iface->get_flags = proto_tree_model_get_flags;
|
||||
iface->get_n_columns = proto_tree_model_get_n_columns;
|
||||
iface->get_column_type = proto_tree_model_get_column_type;
|
||||
iface->get_iter = proto_tree_model_get_iter;
|
||||
iface->get_path = proto_tree_model_get_path;
|
||||
iface->get_value = proto_tree_model_get_value;
|
||||
iface->iter_next = proto_tree_model_iter_next;
|
||||
iface->iter_children = proto_tree_model_iter_children;
|
||||
iface->iter_has_child = proto_tree_model_iter_has_child;
|
||||
iface->iter_n_children = proto_tree_model_iter_n_children;
|
||||
iface->iter_nth_child = proto_tree_model_iter_nth_child;
|
||||
iface->iter_parent = proto_tree_model_iter_parent;
|
||||
}
|
||||
|
||||
static void
|
||||
proto_tree_model_init(ProtoTreeModel *model)
|
||||
{
|
||||
/* To check whether an iter belongs to our model. */
|
||||
model->stamp = g_random_int();
|
||||
}
|
||||
|
||||
static void
|
||||
_class_finalize(GObject *object)
|
||||
{
|
||||
/* must chain up - finalize parent */
|
||||
(*parent_class->finalize)(object);
|
||||
}
|
||||
|
||||
static void
|
||||
proto_tree_model_class_init(ProtoTreeModelClass *klass)
|
||||
{
|
||||
GObjectClass *object_class;
|
||||
|
||||
parent_class = (GObjectClass*) g_type_class_peek_parent(klass);
|
||||
object_class = (GObjectClass*) klass;
|
||||
|
||||
object_class->finalize = _class_finalize;
|
||||
}
|
||||
|
||||
GType
|
||||
proto_tree_model_get_type(void)
|
||||
{
|
||||
static GType proto_tree_type = 0;
|
||||
|
||||
if (proto_tree_type == 0) {
|
||||
static const GTypeInfo proto_tree_info = {
|
||||
sizeof(ProtoTreeModelClass),
|
||||
NULL, /* base_init */
|
||||
NULL, /* base_finalize */
|
||||
(GClassInitFunc) proto_tree_model_class_init,
|
||||
NULL, /* class finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof(ProtoTreeModel),
|
||||
0, /* n_preallocs */
|
||||
(GInstanceInitFunc) proto_tree_model_init,
|
||||
NULL /* value_table */
|
||||
};
|
||||
|
||||
static const GInterfaceInfo tree_model_info = {
|
||||
(GInterfaceInitFunc) proto_tree_model_tree_init,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
/* Register the new derived type with the GObject type system */
|
||||
proto_tree_type = g_type_register_static(G_TYPE_OBJECT,
|
||||
"ProtoTreeModel",
|
||||
&proto_tree_info,
|
||||
(GTypeFlags)0);
|
||||
|
||||
g_type_add_interface_static(proto_tree_type,
|
||||
GTK_TYPE_TREE_MODEL,
|
||||
&tree_model_info);
|
||||
}
|
||||
return proto_tree_type;
|
||||
}
|
||||
|
||||
ProtoTreeModel *
|
||||
proto_tree_model_new(proto_tree *protocol_tree, int display_hidden_proto_items)
|
||||
{
|
||||
ProtoTreeModel *model;
|
||||
|
||||
model = (ProtoTreeModel *) g_object_new(PROTO_TYPE_TREE, NULL);
|
||||
|
||||
g_assert(model != NULL);
|
||||
model->protocol_tree = protocol_tree;
|
||||
model->with_hidden = display_hidden_proto_items;
|
||||
|
||||
return model;
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/* proto_tree_model.h
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef __PROTO_TREE_MODEL_H__
|
||||
#define __PROTO_TREE_MODEL_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#define PROTO_TYPE_TREE (proto_tree_model_get_type())
|
||||
|
||||
#define PROTO_TREE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PROTO_TYPE_TREE, ProtoTreeModel))
|
||||
#define PROTO_IS_TREE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PROTO_TYPE_TREE))
|
||||
|
||||
struct proto_tree_model;
|
||||
typedef struct proto_tree_model ProtoTreeModel;
|
||||
|
||||
GType proto_tree_model_get_type(void);
|
||||
ProtoTreeModel *proto_tree_model_new(proto_tree *protocol_tree, int display_hidden_proto_items);
|
||||
|
||||
#endif /* __PROTO_TREE_MODEL_H__ */
|
Loading…
Reference in New Issue