2 * GTK Tap implementation of stats_tree
3 * 2005, Luis E. G. Ontanon
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 #include <wsutil/report_err.h>
33 #include <epan/stats_tree_priv.h>
35 #include "ui/simple_dialog.h"
36 #include "../globals.h"
37 #include "../stat_menu.h"
39 #include "ui/gtk/gui_utils.h"
40 #include "ui/gtk/dlg_utils.h"
41 #include "ui/gtk/tap_param_dlg.h"
42 #include "ui/gtk/main.h"
44 #include "ui/gtk/old-gtk-compat.h"
46 struct _st_node_pres
{
50 struct _tree_cfg_pres
{
51 tap_param_dlg
* stat_dlg
;
61 /* the columns of the tree pane */
62 enum _stat_tree_columns
{
70 /* used for converting numbers */
71 #define NUM_BUF_SIZE 32
73 /* creates the gtk representation for a stat_node
77 setup_gtk_node_pr(stat_node
* node
)
79 GtkTreeIter
* parent
= NULL
;
81 node
->pr
= (st_node_pres
*)g_malloc(sizeof(st_node_pres
));
83 if (node
->st
->pr
->store
) {
84 node
->pr
->iter
= (GtkTreeIter
*)g_malloc0(sizeof(GtkTreeIter
));
86 if ( node
->parent
&& node
->parent
->pr
) {
87 parent
= node
->parent
->pr
->iter
;
89 gtk_tree_store_append (node
->st
->pr
->store
, node
->pr
->iter
, parent
);
90 gtk_tree_store_set(node
->st
->pr
->store
, node
->pr
->iter
,
91 TITLE_COLUMN
, node
->name
, RATE_COLUMN
, "", COUNT_COLUMN
, "", -1);
97 draw_gtk_node(stat_node
* node
)
99 static gchar value
[NUM_BUF_SIZE
];
100 static gchar rate
[NUM_BUF_SIZE
];
101 static gchar percent
[NUM_BUF_SIZE
];
104 stats_tree_get_strs_from_node(node
, value
, rate
,
107 if (node
->st
->pr
->store
&& node
->pr
->iter
) {
108 gtk_tree_store_set(node
->st
->pr
->store
, node
->pr
->iter
,
111 PERCENT_COLUMN
, percent
,
115 if (node
->children
) {
116 for (child
= node
->children
; child
; child
= child
->next
)
117 draw_gtk_node(child
);
122 draw_gtk_tree(void *psp
)
124 stats_tree
*st
= (stats_tree
*)psp
;
127 for (child
= st
->root
.children
; child
; child
= child
->next
) {
128 draw_gtk_node(child
);
130 if (child
->pr
->iter
&& st
->pr
->store
) {
131 gtk_tree_view_expand_row(GTK_TREE_VIEW(st
->pr
->tree
),
132 gtk_tree_model_get_path(GTK_TREE_MODEL(st
->pr
->store
),
141 free_gtk_tree(GtkWindow
*win _U_
, stats_tree
*st
)
143 remove_tap_listener(st
);
146 st
->root
.pr
->iter
= NULL
;
148 st
->cfg
->in_use
= FALSE
;
154 clear_node_pr(stat_node
* n
)
157 for (c
= n
->children
; c
; c
= c
->next
) {
162 gtk_tree_store_remove(n
->st
->pr
->store
, n
->pr
->iter
);
170 stats_tree
* st
= (stats_tree
*)p
;
172 for (c
= st
->root
.children
; c
; c
= c
->next
) {
179 /* initializes the stats_tree window */
181 init_gtk_tree(const char* opt_arg
, void *userdata _U_
)
183 gchar
*abbr
= stats_tree_get_abbr(opt_arg
);
184 stats_tree
* st
= NULL
;
185 stats_tree_cfg
* cfg
= NULL
;
186 tree_pres
* pr
= (tree_pres
*)g_malloc(sizeof(tree_pres
));
188 gchar
* window_name
= NULL
;
189 GString
* error_string
;
192 GtkWidget
*main_vb
, *bbox
, *bt_close
;
193 GtkTreeViewColumn
* column
;
194 GtkCellRenderer
* renderer
;
197 cfg
= stats_tree_get_cfg_by_abbr(abbr
);
199 if (cfg
&& cfg
->in_use
) {
201 report_failure("cannot open more than one tree of the same type at once");
206 init_strlen
= strlen(cfg
->pr
->stat_dlg
->init_string
);
208 if (strncmp (opt_arg
, cfg
->pr
->stat_dlg
->init_string
, init_strlen
) == 0){
209 if (init_strlen
== strlen(opt_arg
)) {
210 st
= stats_tree_new(cfg
,pr
,NULL
);
212 st
= stats_tree_new(cfg
,pr
,(char*)opt_arg
+init_strlen
+1);
216 st
= stats_tree_new(cfg
,pr
,NULL
);
219 report_failure("no such stats_tree (%s) in stats_tree registry",abbr
);
226 report_failure("could not obtain stats_tree abbr from opt_arg");
233 window_name
= g_strdup_printf("%s Stats Tree", cfg
->name
);
235 st
->pr
->win
= window_new_with_geom(GTK_WINDOW_TOPLEVEL
,window_name
,window_name
);
236 gtk_window_set_default_size(GTK_WINDOW(st
->pr
->win
), 400, 400);
240 title
=g_strdup_printf("%s with filter: %s",cfg
->name
,st
->filter
);
243 title
=g_strdup_printf("%s", cfg
->name
);
246 gtk_window_set_title(GTK_WINDOW(st
->pr
->win
), title
);
249 main_vb
= ws_gtk_box_new(GTK_ORIENTATION_VERTICAL
, 3, FALSE
);
250 gtk_container_set_border_width(GTK_CONTAINER(main_vb
), 12);
251 gtk_container_add(GTK_CONTAINER(st
->pr
->win
), main_vb
);
253 scr_win
= scrolled_window_new(NULL
, NULL
);
255 st
->pr
->store
= gtk_tree_store_new (N_COLUMNS
, G_TYPE_STRING
, G_TYPE_STRING
,
256 G_TYPE_STRING
, G_TYPE_STRING
);
258 st
->pr
->tree
= gtk_tree_view_new_with_model (GTK_TREE_MODEL (st
->pr
->store
));
259 g_object_unref(G_OBJECT(st
->pr
->store
));
261 gtk_container_add( GTK_CONTAINER(scr_win
), st
->pr
->tree
);
264 renderer
= gtk_cell_renderer_text_new ();
265 column
= gtk_tree_view_column_new_with_attributes ("Topic / Item", renderer
,
266 "text", TITLE_COLUMN
,
268 gtk_tree_view_column_set_resizable (column
,TRUE
);
269 gtk_tree_view_column_set_sizing(column
,GTK_TREE_VIEW_COLUMN_AUTOSIZE
);
270 gtk_tree_view_append_column (GTK_TREE_VIEW (st
->pr
->tree
), column
);
272 renderer
= gtk_cell_renderer_text_new ();
273 column
= gtk_tree_view_column_new_with_attributes ("Count", renderer
,
274 "text", COUNT_COLUMN
,
277 gtk_tree_view_column_set_resizable (column
,TRUE
);
278 gtk_tree_view_column_set_sizing(column
,GTK_TREE_VIEW_COLUMN_AUTOSIZE
);
279 gtk_tree_view_append_column (GTK_TREE_VIEW (st
->pr
->tree
), column
);
281 renderer
= gtk_cell_renderer_text_new ();
282 column
= gtk_tree_view_column_new_with_attributes ("Rate (ms)", renderer
,
285 gtk_tree_view_column_set_resizable (column
,TRUE
);
286 gtk_tree_view_column_set_sizing(column
,GTK_TREE_VIEW_COLUMN_AUTOSIZE
);
287 gtk_tree_view_append_column (GTK_TREE_VIEW (st
->pr
->tree
), column
);
289 renderer
= gtk_cell_renderer_text_new ();
290 column
= gtk_tree_view_column_new_with_attributes ("Percent", renderer
,
291 "text", PERCENT_COLUMN
,
293 gtk_tree_view_column_set_resizable(column
,TRUE
);
294 gtk_tree_view_column_set_sizing(column
,GTK_TREE_VIEW_COLUMN_AUTOSIZE
);
295 gtk_tree_view_append_column (GTK_TREE_VIEW (st
->pr
->tree
), column
);
297 gtk_box_pack_start(GTK_BOX(main_vb
), scr_win
, TRUE
, TRUE
, 0);
299 error_string
= register_tap_listener( cfg
->tapname
,
308 /* error, we failed to attach to the tap. clean up */
309 /* destroy_stat_tree_window(st); */
310 report_failure("stats_tree for: %s failed to attach to the tap: %s",cfg
->name
,error_string
->str
);
311 g_string_free(error_string
, TRUE
);
315 bbox
= dlg_button_row_new(GTK_STOCK_CLOSE
, NULL
);
316 gtk_box_pack_start(GTK_BOX(main_vb
), bbox
, FALSE
, FALSE
, 0);
318 bt_close
= (GtkWidget
*)g_object_get_data(G_OBJECT(bbox
), GTK_STOCK_CLOSE
);
319 window_set_cancel_button(st
->pr
->win
, bt_close
, window_cancel_button_cb
);
321 g_signal_connect(GTK_WINDOW(st
->pr
->win
), "delete_event", G_CALLBACK(window_delete_event_cb
), NULL
);
322 g_signal_connect(GTK_WINDOW(st
->pr
->win
), "destroy", G_CALLBACK(free_gtk_tree
), st
);
324 gtk_widget_show_all(st
->pr
->win
);
325 window_present(st
->pr
->win
);
327 cf_retap_packets(&cfile
);
328 gdk_window_raise(gtk_widget_get_window(st
->pr
->win
));
331 static tap_param tree_stat_params
[] = {
332 { PARAM_FILTER
, "Filter", NULL
}
336 register_gtk_stats_tree_tap (gpointer k _U_
, gpointer v
, gpointer p _U_
)
338 stats_tree_cfg
* cfg
= (stats_tree_cfg
*)v
;
340 cfg
->pr
= (tree_cfg_pres
*)g_malloc(sizeof(tree_cfg_pres
));
342 cfg
->pr
->stat_dlg
= (tap_param_dlg
*)g_malloc(sizeof(tap_param_dlg
));
344 cfg
->pr
->stat_dlg
->win_title
= g_strdup_printf("%s Stats Tree",cfg
->name
);
345 cfg
->pr
->stat_dlg
->init_string
= g_strdup_printf("%s,tree",cfg
->abbr
);
346 cfg
->pr
->stat_dlg
->tap_init_cb
= init_gtk_tree
;
347 cfg
->pr
->stat_dlg
->index
= -1;
348 cfg
->pr
->stat_dlg
->nparams
= G_N_ELEMENTS(tree_stat_params
);
349 cfg
->pr
->stat_dlg
->params
= tree_stat_params
;
353 free_tree_presentation(stats_tree
* st
)
359 register_tap_listener_stats_tree_stat(void)
362 stats_tree_presentation(register_gtk_stats_tree_tap
,
368 free_tree_presentation
,
374 void gtk_stats_tree_cb(GtkAction
*action
, gpointer user_data _U_
)
376 const gchar
*action_name
;
378 stats_tree_cfg
* cfg
= NULL
;
380 action_name
= gtk_action_get_name (action
);
381 abbr
= strrchr(action_name
,'/');
385 abbr
= g_strdup_printf("%s",action_name
);
387 cfg
= stats_tree_get_cfg_by_abbr(abbr
);
389 tap_param_dlg_cb(action
, cfg
->pr
->stat_dlg
);
391 simple_dialog(ESD_TYPE_ERROR
, ESD_BTN_OK
,
392 "Failed to find the stat tree named %s",