Fix build by #if 0 out unused de_sgsap_tmsi() function.
[obnox/wireshark/wip.git] / gtk / dissector_tables_dlg.c
1 /* dissector_tables_dlg.c
2  * dissector_tables_dlg   2010 Anders Broman
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  * 
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  * 
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  * 
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #ifdef HAVE_SYS_TYPES_H
30 # include <sys/types.h>
31 #endif
32 #include <string.h>
33
34 #include <glib.h>
35
36 #include <epan/packet.h>
37
38 #include <gtk/gtk.h>
39 #include "gtk/gui_utils.h"
40 #include "gtk/dlg_utils.h"
41 #include "gtk/dissector_tables_dlg.h"
42
43 static GtkWidget  *dissector_tables_dlg_w = NULL;
44
45 /* The columns */
46 enum
47 {
48     TABLE_UI_NAME_COL,
49     TABLE_SHORT_NAME_COL,
50     N_COLUMNS
51 };
52
53 static void
54 win_destroy_cb(GtkWindow *win _U_, gpointer data _U_)
55 {
56
57     if (dissector_tables_dlg_w != NULL) {
58         window_destroy(dissector_tables_dlg_w);
59         dissector_tables_dlg_w = NULL;
60     }
61
62
63 }
64
65 /*
66  * For a dissector table, put 
67  * its short name and its
68  * descriptive name in the treeview.
69  */
70
71 struct dissector_tables_tree_info {
72     GtkWidget       *tree;
73     GtkTreeIter     iter; 
74     GtkTreeIter     new_iter;
75 };
76
77 typedef struct dissector_tables_tree_info dissector_tables_tree_info_t;
78
79 static gint
80 ui_sort_func(GtkTreeModel *model,
81              GtkTreeIter  *a,
82              GtkTreeIter  *b,
83              gpointer      user_data)
84 {
85     gchar *stra, *strb;
86
87     /* The col to get data from is in userdata */
88     gint data_column = GPOINTER_TO_INT(user_data);
89
90     gtk_tree_model_get(model, a, data_column, &stra, -1);
91     gtk_tree_model_get(model, b, data_column, &strb, -1);
92
93     return strcmp(stra, strb);
94 }
95
96
97 /*
98  * Struct to hold the pointer to the trees
99  * for dissector tables.
100  */
101 struct dissector_tables_trees {
102     GtkWidget       *str_tree_wgt;
103     GtkWidget       *uint_tree_wgt;
104 };
105
106 typedef struct dissector_tables_trees dissector_tables_trees_t;
107
108 static void 
109 proto_add_to_list(dissector_tables_tree_info_t *tree_info,
110                   GtkTreeStore *store, 
111                   gchar        *str,
112                   const gchar  *proto_name)
113 {
114 #if GTK_CHECK_VERSION(2,10,0)
115     gtk_tree_store_insert_with_values(store, &tree_info->new_iter, &tree_info->iter, G_MAXINT,
116                                       TABLE_UI_NAME_COL,    str,
117                                       TABLE_SHORT_NAME_COL, proto_name,
118                                       -1);
119 #else
120     gtk_tree_store_append(store, &tree_info->new_iter, &tree_info->iter);
121     gtk_tree_store_set (store, &tree_info->new_iter,
122                         TABLE_UI_NAME_COL,    str,
123                         TABLE_SHORT_NAME_COL, proto_name,
124                         -1);
125 #endif
126
127 }
128
129 static void
130 decode_proto_add_to_list (const gchar *table_name _U_, ftenum_t selector_type _U_,
131                           gpointer key, gpointer value _U_, gpointer user_data)
132 {
133     GtkTreeStore       *store;
134     const gchar        *proto_name;
135     dtbl_entry_t       *dtbl_entry;
136     dissector_handle_t  handle;
137     guint32             port;
138     gchar              *str;
139     dissector_tables_tree_info_t *tree_info;
140
141     tree_info = user_data;
142     dtbl_entry = value;
143     handle = dtbl_entry_get_handle(dtbl_entry);
144     proto_name = dissector_handle_get_short_name(handle);
145
146     store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(tree_info->tree)));
147
148     switch (selector_type) {
149
150     case FT_UINT8:
151     case FT_UINT16:
152     case FT_UINT24:
153     case FT_UINT32:
154         port = GPOINTER_TO_UINT(key);
155         /* Hack: Use fixed width rj str so alpha sort (strcmp) will sort field numerically */
156         str = g_strdup_printf ("%10d", port);
157         proto_add_to_list(tree_info, store, str, proto_name);
158         g_free (str);
159         break;
160
161     case FT_STRING:
162     case FT_STRINGZ:
163         str = (gchar*) key;
164         proto_add_to_list(tree_info, store, str, proto_name);
165         break;
166
167     default:
168         g_assert_not_reached();
169     }
170
171 }
172
173 static void 
174 table_name_add_to_list(dissector_tables_tree_info_t  *tree_info,
175                        GtkWidget  *tree_view, 
176                        const char *table_name,
177                        const char *ui_name)
178 {
179     GtkTreeStore *store;
180
181     tree_info->tree = tree_view;
182     store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(tree_view))); /* Get store */
183
184 #if GTK_CHECK_VERSION(2,10,0)
185     gtk_tree_store_insert_with_values(store, &tree_info->iter, NULL, G_MAXINT,
186                                       TABLE_UI_NAME_COL,    ui_name,
187                                       TABLE_SHORT_NAME_COL, table_name,
188                                       -1);
189 #else
190     gtk_tree_store_append (store, &tree_info->iter, NULL);  /* Acquire an iterator */
191     gtk_tree_store_set (store, &tree_info->iter,
192                         TABLE_UI_NAME_COL,    ui_name,
193                         TABLE_SHORT_NAME_COL, table_name,
194                         -1);
195 #endif
196
197 }
198
199 static void
200 display_dissector_table_names(const char *table_name, const char *ui_name,
201                               gpointer w)
202 {
203     dissector_tables_trees_t      *dis_tbl_trees;
204     dissector_tables_tree_info_t  *tree_info;
205     ftenum_t                       selector_type = get_dissector_table_selector_type(table_name);
206
207     tree_info = g_new(dissector_tables_tree_info_t, 1);
208     dis_tbl_trees = w;
209
210     switch (selector_type) {
211         case FT_UINT8:
212         case FT_UINT16:
213         case FT_UINT24:
214         case FT_UINT32:
215             table_name_add_to_list(tree_info, dis_tbl_trees->uint_tree_wgt, table_name, ui_name);
216             break;
217         case FT_STRING:
218         case FT_STRINGZ:
219             table_name_add_to_list(tree_info, dis_tbl_trees->str_tree_wgt, table_name, ui_name);
220             break;
221         default:
222             break;
223     }
224     dissector_table_foreach(table_name, decode_proto_add_to_list, tree_info);
225
226     g_free(tree_info);
227 }
228
229 static GtkWidget* 
230 init_table(void)
231 {
232     GtkTreeStore      *store;
233     GtkWidget         *tree;
234     GtkTreeView       *tree_view;
235     GtkTreeViewColumn *column;
236     GtkCellRenderer   *renderer;
237     GtkTreeSortable   *sortable;
238
239     /* Create the store */
240     store = gtk_tree_store_new (N_COLUMNS,      /* Total number of columns */
241                                G_TYPE_STRING,   /* Table              */
242                                G_TYPE_STRING);  /* Table              */
243
244     /* Create a view */
245     tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
246     tree_view = GTK_TREE_VIEW(tree);
247     sortable = GTK_TREE_SORTABLE(store);
248
249 #if GTK_CHECK_VERSION(2,6,0)
250     /* Speed up the list display */
251     gtk_tree_view_set_fixed_height_mode(tree_view, TRUE);
252 #endif
253
254     /* Setup the sortable columns */
255     gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW (tree), FALSE);
256
257     /* The view now holds a reference.  We can get rid of our own reference */
258     g_object_unref (G_OBJECT (store));
259
260     /* Create the first column, associating the "text" attribute of the
261      * cell_renderer to the first column of the model */
262     renderer = gtk_cell_renderer_text_new ();
263     column = gtk_tree_view_column_new_with_attributes ("UI name", renderer, "text", TABLE_UI_NAME_COL, NULL);
264     gtk_tree_sortable_set_sort_func(sortable, TABLE_UI_NAME_COL, 
265                                     ui_sort_func, GINT_TO_POINTER(TABLE_UI_NAME_COL), NULL);
266     gtk_tree_view_column_set_sort_column_id(column, TABLE_UI_NAME_COL);
267     gtk_tree_view_column_set_resizable(column, TRUE);
268     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
269     gtk_tree_view_column_set_min_width(column, 80);
270     gtk_tree_view_column_set_fixed_width(column, 330);
271     gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
272
273     renderer = gtk_cell_renderer_text_new ();
274     column = gtk_tree_view_column_new_with_attributes ("Short name", renderer, "text", TABLE_SHORT_NAME_COL, NULL);
275     gtk_tree_sortable_set_sort_func(sortable, TABLE_SHORT_NAME_COL, 
276                                     ui_sort_func, GINT_TO_POINTER(TABLE_SHORT_NAME_COL), NULL);
277     gtk_tree_view_column_set_sort_column_id(column, TABLE_SHORT_NAME_COL);
278     gtk_tree_view_column_set_resizable(column, TRUE);
279     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
280     gtk_tree_view_column_set_min_width(column, 80);
281     gtk_tree_view_column_set_fixed_width(column, 100);
282     gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
283
284     return tree;
285
286 }
287
288 static void
289 dissector_tables_dlg_init(void)
290 {
291     dissector_tables_trees_t dis_tbl_trees;
292     GtkWidget       *vbox;
293     GtkWidget       *hbox;
294     GtkWidget       *main_nb;
295     GtkWidget       *scrolled_window;
296     GtkTreeSortable *sortable;
297     GtkWidget       *temp_page, *tmp;
298
299     dissector_tables_dlg_w = dlg_window_new("Dissector tables");  /* transient_for top_level */
300     gtk_window_set_destroy_with_parent (GTK_WINDOW(dissector_tables_dlg_w), TRUE);
301     gtk_window_set_default_size(GTK_WINDOW(dissector_tables_dlg_w), 700, 300);
302
303     vbox=gtk_vbox_new(FALSE, 3);
304     gtk_container_add(GTK_CONTAINER(dissector_tables_dlg_w), vbox);
305     gtk_container_set_border_width(GTK_CONTAINER(vbox), 12);
306
307     main_nb = gtk_notebook_new();
308     gtk_box_pack_start(GTK_BOX(vbox), main_nb, TRUE, TRUE, 0);
309
310     /* String tables */
311     temp_page = gtk_vbox_new(FALSE, 6);
312     tmp = gtk_label_new("String tables");
313     gtk_widget_show(tmp);
314     hbox = gtk_hbox_new(FALSE, 3);
315     gtk_container_add(GTK_CONTAINER(hbox), tmp);
316     gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), temp_page, hbox);
317
318     scrolled_window = scrolled_window_new(NULL, NULL);
319     dis_tbl_trees.str_tree_wgt = init_table();
320     gtk_widget_show(dis_tbl_trees.str_tree_wgt);
321     gtk_container_add(GTK_CONTAINER(scrolled_window), dis_tbl_trees.str_tree_wgt);
322     gtk_box_pack_start(GTK_BOX(temp_page), scrolled_window, TRUE, TRUE, 0);
323     gtk_widget_show(scrolled_window);
324
325     /* uint tables */
326     temp_page = gtk_vbox_new(FALSE, 6);
327     tmp = gtk_label_new("Integer tables");
328     gtk_widget_show(tmp);
329     hbox = gtk_hbox_new(FALSE, 3);
330     gtk_container_add(GTK_CONTAINER(hbox), tmp);
331     gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), temp_page, hbox);
332
333     scrolled_window = scrolled_window_new(NULL, NULL);
334     dis_tbl_trees.uint_tree_wgt = init_table();
335     gtk_widget_show(dis_tbl_trees.uint_tree_wgt);
336     gtk_container_add(GTK_CONTAINER(scrolled_window), dis_tbl_trees.uint_tree_wgt);
337     gtk_box_pack_start(GTK_BOX(temp_page), scrolled_window, TRUE, TRUE, 0);
338     gtk_widget_show(scrolled_window);
339
340     /* We must display TOP LEVEL Widget before calling init_table() */
341     gtk_widget_show_all(dissector_tables_dlg_w);
342     g_signal_connect(dissector_tables_dlg_w, "destroy", G_CALLBACK(win_destroy_cb), NULL);
343
344     /* Fill the table with data */
345     dissector_all_tables_foreach_table(display_dissector_table_names, (gpointer)&dis_tbl_trees);
346
347     sortable = GTK_TREE_SORTABLE(gtk_tree_view_get_model(GTK_TREE_VIEW(dis_tbl_trees.str_tree_wgt)));
348     gtk_tree_sortable_set_sort_column_id(sortable, TABLE_UI_NAME_COL, GTK_SORT_ASCENDING);
349
350     sortable = GTK_TREE_SORTABLE(gtk_tree_view_get_model(GTK_TREE_VIEW(dis_tbl_trees.uint_tree_wgt)));
351     gtk_tree_sortable_set_sort_column_id(sortable, TABLE_UI_NAME_COL, GTK_SORT_ASCENDING);
352
353 }
354
355 void
356 dissector_tables_dlg_cb(GtkWidget *w _U_, gpointer d _U_)
357 {
358     if (dissector_tables_dlg_w) {
359           reactivate_window(dissector_tables_dlg_w);
360     } else {
361           dissector_tables_dlg_init();
362     }
363 }