Synchronize the selection of interfaces between the main welcome
[obnox/wireshark/wip.git] / gtk / expert_comp_dlg.c
1 /* expert_comp_dlg.c
2  * expert_comp_dlg   2005 Greg Morris
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 <gtk/gtk.h>
35
36 #include <epan/packet_info.h>
37 #include <epan/tap.h>
38 #include <epan/stat_cmd_args.h>
39 #include <epan/prefs.h>
40
41 #include "../simple_dialog.h"
42 #include "../stat_menu.h"
43
44 #include "gtk/gui_utils.h"
45 #include "gtk/dlg_utils.h"
46 #include "gtk/expert_comp_table.h"
47 #include "gtk/gui_stat_menu.h"
48 #include "gtk/help_dlg.h"
49 #include "gtk/expert_comp_dlg.h"
50 #include "gtk/stock_icons.h"
51 #include "gtk/main.h"
52
53 #include "gtk/main_proto_draw.h"
54
55
56 enum
57 {
58     NO_COLUMN,
59     SEVERITY_COLUMN,
60     GROUP_COLUMN,
61     PROTOCOL_COLUMN,
62     SUMMARY_COLUMN,
63     FOREGROUND_COLOR_COL,
64     BACKGROUND_COLOR_COL,
65     N_COLUMNS
66 };
67
68 /* used to keep track of the statistics for an entire program interface */
69 typedef struct _expert_comp_dlg_t {
70     GtkWidget *win;
71     GtkWidget *chat_label;
72     GtkWidget *note_label;
73     GtkWidget *warn_label;
74     GtkWidget *error_label;
75     GtkWidget *all_label;
76     error_equiv_table chat_table;
77     error_equiv_table note_table;
78     error_equiv_table warn_table;
79     error_equiv_table error_table;
80     guint32 disp_events;
81     guint32 chat_events;
82     guint32 note_events;
83     guint32 warn_events;
84     guint32 error_events;
85 } expert_comp_dlg_t;
86
87 struct expert_tapdata_s {
88         GtkWidget       *win;
89         GtkWidget       *scrolled_window;
90         GtkTreeView *tree_view;
91         GtkWidget       *label;
92         guint32         disp_events;
93         guint32         chat_events;
94         guint32         note_events;
95         guint32         warn_events;
96         guint32         error_events;
97         int             severity_report_level;
98
99         GArray          *ei_array;      /* expert info items */
100         guint           first;
101         guint           last;
102         GStringChunk*   text;           /* summary text */
103 };
104
105 static GtkWidget  *expert_comp_dlg_w = NULL;
106
107 static void
108 select_row_cb(GtkTreeSelection *selection, gpointer *user_data _U_)
109 {
110     /*guint num = GPOINTER_TO_UINT(gtk_clist_get_row_data(clist, row));*/
111
112     /*cf_goto_frame(&cfile, num);*/
113
114     GtkTreeIter iter;
115     GtkTreeModel *model;
116     guint fnumber;
117
118     if (selection==NULL)
119         return;
120
121     if (gtk_tree_selection_get_selected (selection, &model, &iter)){
122         gtk_tree_model_get (model, &iter, NO_COLUMN, &fnumber, -1);
123         cf_goto_frame(&cfile, fnumber);
124     }
125
126 }
127
128 /* reset of display only, e.g. for filtering */
129 static void expert_dlg_display_reset(expert_tapdata_t * etd)
130 {
131     etd->disp_events = 0;
132     gtk_list_store_clear(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(etd->tree_view))));
133
134     gtk_window_set_title(GTK_WINDOW(etd->win), "Wireshark: ? Expert Infos");
135     if(etd->label) {
136         gtk_label_set_text(GTK_LABEL(etd->label), "Please wait ...");
137     }
138 }
139
140 /* complete reset, e.g. capture file closed */
141 static void
142 expert_dlg_reset(void *tapdata)
143 {
144     expert_tapdata_t * etd = tapdata;
145
146     etd->chat_events = 0;
147     etd->note_events = 0;
148     etd->warn_events = 0;
149     etd->error_events = 0;
150     etd->last = 0;
151     etd->first = 0;
152     /* g_string_chunk_clear() is introduced in glib 2.14 */
153     g_string_chunk_free(etd->text);
154     etd->text = g_string_chunk_new(100);
155     g_array_set_size(etd->ei_array, 0);
156
157     expert_dlg_display_reset(etd);
158 }
159
160 static int
161 expert_dlg_packet(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *pointer)
162 {
163     expert_info_t    *ei;
164     expert_tapdata_t *etd = tapdata;
165
166     g_array_append_val(etd->ei_array, *(expert_info_t *)pointer);
167     etd->last = etd->ei_array->len;
168     ei = &g_array_index(etd->ei_array, expert_info_t, etd->last -1); /* ugly */
169     ei->protocol = g_string_chunk_insert_const(etd->text, ei->protocol);
170     ei->summary = g_string_chunk_insert_const(etd->text, ei->summary);
171
172     switch(ei->severity) {
173     case(PI_CHAT):
174         etd->chat_events++;
175         break;
176     case(PI_NOTE):
177         etd->note_events++;
178         break;
179     case(PI_WARN):
180         etd->warn_events++;
181         break;
182     case(PI_ERROR):
183         etd->error_events++;
184         break;
185     default:
186         g_assert_not_reached();
187     }
188     if(ei->severity < etd->severity_report_level) {
189         return 0; /* draw not required */
190     } else {
191         return 1; /* draw required */
192     }
193 }
194 static void
195 error_set_title(expert_comp_dlg_t *ss)
196 {
197     char *title;
198
199     title = g_strdup_printf("Expert Info Composite: %s",
200         cf_get_display_name(&cfile));
201     gtk_window_set_title(GTK_WINDOW(ss->win), title);
202     g_free(title);
203 }
204
205 static void
206 error_reset(void *pss)
207 {
208     expert_comp_dlg_t *ss=(expert_comp_dlg_t *)pss;
209     gchar *buf;
210
211     ss->error_events = 0;
212     ss->warn_events = 0;
213     ss->note_events = 0;
214     ss->chat_events = 0;
215     ss->disp_events = 0;
216
217     reset_error_table_data(&ss->error_table);
218     buf = g_strdup_printf("Errors: %u (0)", ss->error_table.num_procs);
219     gtk_label_set_text( GTK_LABEL(ss->error_label), buf);
220     g_free(buf);
221
222     reset_error_table_data(&ss->warn_table);
223     buf = g_strdup_printf("Warnings: %u (0)", ss->warn_table.num_procs);
224     gtk_label_set_text( GTK_LABEL(ss->warn_label), buf);
225     g_free(buf);
226
227     reset_error_table_data(&ss->note_table);
228     buf = g_strdup_printf("Notes: %u (0)", ss->note_table.num_procs);
229     gtk_label_set_text( GTK_LABEL(ss->note_label), buf);
230     g_free(buf);
231
232     reset_error_table_data(&ss->chat_table);
233     buf = g_strdup_printf("Chats: %u (0)", ss->chat_table.num_procs);
234     gtk_label_set_text( GTK_LABEL(ss->chat_label), buf);
235     g_free(buf);
236
237     gtk_label_set_text( GTK_LABEL(ss->all_label), "Details: 0");
238     error_set_title(ss);
239 }
240
241 static gboolean
242 error_packet(void *pss, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *prv)
243 {
244     expert_comp_dlg_t *ss=(expert_comp_dlg_t *)pss;
245     const expert_info_t *error_pkt=prv;
246
247     /* if return value is 0 then no error */
248     if(error_pkt==NULL){
249         return FALSE;
250     }
251
252     switch (error_pkt->severity) {
253     case PI_ERROR:
254         ss->disp_events++;
255         ss->error_events++;
256         init_error_table_row(&ss->error_table, error_pkt);
257         break;
258     case PI_WARN:
259         ss->disp_events++;
260         ss->warn_events++;
261         init_error_table_row(&ss->warn_table, error_pkt);
262         break;
263     case PI_NOTE:
264         ss->disp_events++;
265         ss->note_events++;
266         init_error_table_row(&ss->note_table, error_pkt);
267         break;
268     case PI_CHAT:
269         ss->disp_events++;
270         ss->chat_events++;
271         init_error_table_row(&ss->chat_table, error_pkt);
272         break;
273     default:
274         return FALSE; /* Don't draw */
275     }
276     return TRUE; /* Draw */
277 }
278
279 static void
280 expert_comp_draw(void *data)
281 {
282     gchar *buf = NULL;
283
284     expert_comp_dlg_t *ss=(expert_comp_dlg_t *)data;
285
286     buf = g_strdup_printf("Errors: %u (%u)", ss->error_table.num_procs, ss->error_events);
287     gtk_label_set_text( GTK_LABEL(ss->error_label), buf);
288     g_free(buf);
289
290     buf = g_strdup_printf("Warnings: %u (%u)", ss->warn_table.num_procs, ss->warn_events);
291     gtk_label_set_text( GTK_LABEL(ss->warn_label), buf);
292     g_free(buf);
293
294     buf = g_strdup_printf("Notes: %u (%u)", ss->note_table.num_procs, ss->note_events);
295     gtk_label_set_text( GTK_LABEL(ss->note_label), buf);
296     g_free(buf);
297
298     buf = g_strdup_printf("Chats: %u (%u)", ss->chat_table.num_procs, ss->chat_events);
299     gtk_label_set_text( GTK_LABEL(ss->chat_label), buf);
300     g_free(buf);
301
302     buf = g_strdup_printf("Details: %u", ss->disp_events);
303     gtk_label_set_text( GTK_LABEL(ss->all_label), buf);
304     g_free(buf);
305
306 }
307
308 static void
309 win_destroy_cb(GtkWindow *win _U_, gpointer data)
310 {
311     expert_comp_dlg_t *ss=(expert_comp_dlg_t *)data;
312
313     protect_thread_critical_region();
314     remove_tap_listener(ss);
315     unprotect_thread_critical_region();
316
317     if (expert_comp_dlg_w != NULL) {
318         window_destroy(expert_comp_dlg_w);
319         expert_comp_dlg_w = NULL;
320     }
321
322     free_error_table_data(&ss->error_table);
323     free_error_table_data(&ss->warn_table);
324     free_error_table_data(&ss->note_table);
325     free_error_table_data(&ss->chat_table);
326     g_free(ss);
327
328 }
329
330 static void
331 expert_dlg_destroy_cb(GtkWindow *win _U_, gpointer data)
332 {
333     expert_tapdata_t *etd=(expert_tapdata_t *)data;
334
335     protect_thread_critical_region();
336     remove_tap_listener(etd);
337     unprotect_thread_critical_region();
338
339     /*free_srt_table_data(&etd->afp_srt_table);*/
340     g_array_free(etd->ei_array, TRUE);
341     g_string_chunk_free(etd->text);
342     g_free(etd);
343 }
344
345 static expert_tapdata_t * expert_dlg_new_table(void)
346 {
347     expert_tapdata_t * etd;
348     etd=g_malloc0(sizeof(expert_tapdata_t));
349
350     etd->ei_array = g_array_sized_new(FALSE, FALSE, sizeof(expert_info_t), 1000);
351     etd->text = g_string_chunk_new(100);
352     etd->severity_report_level = PI_CHAT;
353     return etd;
354 }
355
356 static void
357 expert_dlg_init_table(expert_tapdata_t * etd, GtkWidget *vbox)
358 {
359     GtkListStore *store;
360     GtkWidget *tree;
361     GtkTreeViewColumn *column;
362     GtkCellRenderer *renderer;
363     GtkTreeSortable *sortable;
364     GtkTreeSelection  *selection;
365
366     /* Create the store */
367     store = gtk_list_store_new(N_COLUMNS,        /* Total number of columns */
368                                G_TYPE_UINT,      /* No                   */
369                                G_TYPE_POINTER,   /* Severity           */
370                                G_TYPE_POINTER,   /* Group              */
371                                G_TYPE_POINTER,    /* Protocol           */
372                                G_TYPE_POINTER,    /* Summary            */
373                                G_TYPE_STRING,    /* forground          */
374                                G_TYPE_STRING);   /* Background         */
375
376     /* Create a view */
377     tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
378     etd->tree_view = GTK_TREE_VIEW(tree);
379     sortable = GTK_TREE_SORTABLE(store);
380
381     /* Speed up the list display */
382     gtk_tree_view_set_fixed_height_mode(etd->tree_view, TRUE);
383
384     /* Setup the sortable columns */
385     gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW (tree), FALSE);
386
387     /* The view now holds a reference.  We can get rid of our own reference */
388     g_object_unref (G_OBJECT (store));
389
390     /* Let the font be the default one to have the same look as the rest of the tabs
391          * Bug https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=4388
392          * gtk_widget_modify_font(GTK_WIDGET (etd->tree_view), user_font_get_regular());
393          */
394
395     /* Create a cell renderer */
396     renderer = gtk_cell_renderer_text_new ();
397     g_object_set(renderer, "ypad", 0, NULL);
398     g_object_set(renderer, "xalign", 1.0, NULL);
399
400     /* Create the first column, associating the "text" attribute of the
401      * cell_renderer to the first column of the model */
402     /* No */
403     column = gtk_tree_view_column_new_with_attributes ("No", renderer,
404         "text", NO_COLUMN,
405         "foreground", FOREGROUND_COLOR_COL,
406         "background", BACKGROUND_COLOR_COL,
407         NULL);
408     gtk_tree_view_column_set_sort_column_id(column, NO_COLUMN);
409     gtk_tree_view_column_set_resizable(column, TRUE);
410     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
411     gtk_tree_view_column_set_min_width(column, 80);
412     gtk_tree_view_append_column (etd->tree_view, column);
413
414     /* Severity */
415     renderer = gtk_cell_renderer_text_new ();
416     g_object_set(renderer, "ypad", 0, NULL);
417
418     column = gtk_tree_view_column_new_with_attributes ("Severity", renderer,
419         "foreground", FOREGROUND_COLOR_COL,
420         "background", BACKGROUND_COLOR_COL,
421         NULL);
422
423         gtk_tree_view_column_set_cell_data_func(column, renderer, str_ptr_data_func,
424                 GINT_TO_POINTER(SEVERITY_COLUMN), NULL);
425
426         gtk_tree_sortable_set_sort_func(sortable, SEVERITY_COLUMN, str_ptr_sort_func,
427                 GINT_TO_POINTER(SEVERITY_COLUMN), NULL);
428
429     gtk_tree_view_column_set_sort_column_id(column, SEVERITY_COLUMN);
430     gtk_tree_view_column_set_resizable(column, TRUE);
431     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
432     gtk_tree_view_column_set_min_width(column, 80);
433     /* Add the column to the view. */
434     gtk_tree_view_append_column (etd->tree_view, column);
435
436     /* Group */
437     renderer = gtk_cell_renderer_text_new ();
438     g_object_set(renderer, "ypad", 0, NULL);
439     column = gtk_tree_view_column_new_with_attributes ("Group", renderer,
440         "foreground", FOREGROUND_COLOR_COL,
441         "background", BACKGROUND_COLOR_COL,
442         NULL);
443
444         gtk_tree_view_column_set_cell_data_func(column, renderer, str_ptr_data_func,
445                 GINT_TO_POINTER(GROUP_COLUMN), NULL);
446
447         gtk_tree_sortable_set_sort_func(sortable, GROUP_COLUMN, str_ptr_sort_func,
448                 GINT_TO_POINTER(GROUP_COLUMN), NULL);
449
450     gtk_tree_view_column_set_sort_column_id(column, GROUP_COLUMN);
451     gtk_tree_view_column_set_resizable(column, TRUE);
452     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
453     gtk_tree_view_column_set_min_width(column, 80);
454     /* Add the column to the view. */
455     gtk_tree_view_append_column (etd->tree_view, column);
456
457     /* Protocol. */
458     renderer = gtk_cell_renderer_text_new ();
459     g_object_set(renderer, "ypad", 0, NULL);
460     column = gtk_tree_view_column_new_with_attributes ("Protocol", renderer,
461         "foreground", FOREGROUND_COLOR_COL,
462         "background", BACKGROUND_COLOR_COL,
463         NULL);
464         gtk_tree_view_column_set_cell_data_func(column, renderer, str_ptr_data_func,
465                 GINT_TO_POINTER(PROTOCOL_COLUMN), NULL);
466
467         gtk_tree_sortable_set_sort_func(sortable, PROTOCOL_COLUMN, str_ptr_sort_func,
468                 GINT_TO_POINTER(PROTOCOL_COLUMN), NULL);
469
470     gtk_tree_view_column_set_sort_column_id(column, PROTOCOL_COLUMN);
471     gtk_tree_view_column_set_resizable(column, TRUE);
472     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
473     gtk_tree_view_column_set_min_width(column, 80);
474     gtk_tree_view_append_column (etd->tree_view, column);
475
476     /* Summary. */
477     renderer = gtk_cell_renderer_text_new ();
478     g_object_set(renderer, "ypad", 0, NULL);
479     column = gtk_tree_view_column_new_with_attributes ("Summary", renderer,
480         "foreground", FOREGROUND_COLOR_COL,
481         "background", BACKGROUND_COLOR_COL,
482         NULL);
483         gtk_tree_view_column_set_cell_data_func(column, renderer, str_ptr_data_func,
484                 GINT_TO_POINTER(SUMMARY_COLUMN), NULL);
485
486         gtk_tree_sortable_set_sort_func(sortable, SUMMARY_COLUMN, str_ptr_sort_func,
487                 GINT_TO_POINTER(SUMMARY_COLUMN), NULL);
488
489     gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
490     gtk_tree_view_column_set_min_width(column, 90);
491     gtk_tree_view_column_set_sort_column_id(column, SUMMARY_COLUMN);
492     gtk_tree_view_column_set_resizable(column, TRUE);
493     gtk_tree_view_append_column (etd->tree_view, column);
494
495
496     gtk_tree_view_set_search_column (etd->tree_view, SUMMARY_COLUMN); /* Allow searching the summary */
497     gtk_tree_view_set_reorderable (etd->tree_view, TRUE);   /* Allow user to reorder data with drag n drop */
498
499     /* Now enable the sorting of each column */
500     gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(etd->tree_view), TRUE);
501     gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(etd->tree_view), TRUE);
502
503     /* Setup the selection handler */
504     selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(etd->tree_view));
505     gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
506
507     g_signal_connect (G_OBJECT (selection), "changed", /* select_row */
508                   G_CALLBACK (select_row_cb),
509                   NULL);
510
511     etd->scrolled_window=scrolled_window_new(NULL, NULL);
512     gtk_container_add(GTK_CONTAINER(etd->scrolled_window), GTK_WIDGET (etd->tree_view));
513
514     gtk_box_pack_start(GTK_BOX(vbox), etd->scrolled_window, TRUE, TRUE, 0);
515 }
516
517 static void
518 expert_dlg_draw(void *data)
519 {
520     expert_tapdata_t *etd = data;
521     expert_info_t *ei;
522     gchar *title;
523     const char *entries[2];   /**< column entries */
524     GtkListStore *list_store;
525     GtkTreeIter iter;
526     gchar *color_str = NULL;
527     guint packet_no = 0;
528         const gchar *group_str;
529         const gchar *severity_str;
530
531
532     if(etd->label) {
533         if(etd->last - etd->first) {
534             title = g_strdup_printf("Adding: %u new messages",etd->last - etd->first);
535             gtk_label_set_text(GTK_LABEL(etd->label), title);
536             g_free(title);
537         }
538     }
539
540     /* append new events (remove from new list, append to displayed list and clist) */
541     while(etd->first < etd->last){
542         ei = &g_array_index(etd->ei_array, expert_info_t, etd->first);
543         etd->first++;
544
545         if(ei->severity < etd->severity_report_level) {
546             continue;
547         }
548         etd->disp_events++;
549
550         /* packet number */
551         if(ei->packet_num) {
552             packet_no = ei->packet_num;
553         }
554
555         /*  match_strval return a static string or NULL
556             severity */
557                 severity_str = match_strval(ei->severity, expert_severity_vals);
558         /* group */
559                 group_str = match_strval(ei->group, expert_group_vals);
560
561         /* protocol */
562         if(ei->protocol) {
563             entries[0] = ei->protocol;
564         } else {
565             entries[0] = "-";
566         }
567
568         /* summary */
569         entries[1] = ei->summary;
570
571         /* set rows background color depending on severity */
572         switch(ei->severity) {
573         case(PI_CHAT):
574             color_str = expert_color_chat_str;
575             break;
576         case(PI_NOTE):
577             color_str = expert_color_note_str;
578             break;
579         case(PI_WARN):
580             color_str = expert_color_warn_str;
581             break;
582         case(PI_ERROR):
583             color_str = expert_color_error_str;
584             break;
585         default:
586             g_assert_not_reached();
587         }
588
589         list_store = GTK_LIST_STORE(gtk_tree_view_get_model(etd->tree_view)); /* Get store */
590
591         /* Creates a new row at position. iter will be changed to point to this new row.
592          * If position is larger than the number of rows on the list, then the new row will be appended to the list.
593          * The row will be filled with the values given to this function.
594          * :
595          * should generally be preferred when inserting rows in a sorted list store.
596          */
597         gtk_list_store_insert_with_values( list_store , &iter, G_MAXINT,
598                     NO_COLUMN, packet_no,
599                     SEVERITY_COLUMN, severity_str,
600                     GROUP_COLUMN, group_str,
601                     PROTOCOL_COLUMN, entries[0],
602                     SUMMARY_COLUMN, entries[1],
603                     FOREGROUND_COLOR_COL, expert_color_foreground_str,
604                     BACKGROUND_COLOR_COL, color_str,
605                     -1);
606     }
607
608     if(etd->label) {
609         title = g_strdup_printf("Errors: %u Warnings: %u Notes: %u Chats: %u",
610                                 etd->error_events, etd->warn_events,
611                                 etd->note_events, etd->chat_events);
612         gtk_label_set_text(GTK_LABEL(etd->label), title);
613         g_free(title);
614     }
615
616     title = g_strdup_printf("Wireshark: %u Expert Info%s",
617                             etd->disp_events,
618                             plurality(etd->disp_events, "", "s"));
619     gtk_window_set_title(GTK_WINDOW(etd->win), title);
620     g_free(title);
621 }
622
623 static void
624 expert_comp_init(const char *optarg _U_, void* userdata _U_)
625 {
626     expert_comp_dlg_t *ss;
627     const char *filter=NULL;
628     GString *error_string;
629     GtkWidget *temp_page;
630     GtkWidget *main_nb;
631     GtkWidget *vbox;
632     GtkWidget *hbox;
633     GtkWidget *bbox;
634     GtkWidget *close_bt;
635     GtkWidget *help_bt;
636     expert_tapdata_t *etd;
637  
638     ss=g_malloc(sizeof(expert_comp_dlg_t));
639
640     ss->disp_events = 0;
641     ss->chat_events = 0;
642     ss->note_events = 0;
643     ss->warn_events = 0;
644     ss->error_events = 0;
645
646     expert_comp_dlg_w = ss->win=dlg_window_new("err");  /* transient_for top_level */
647     gtk_window_set_destroy_with_parent (GTK_WINDOW(ss->win), TRUE);
648     gtk_window_set_default_size(GTK_WINDOW(ss->win), 700, 300);
649
650     error_set_title(ss);
651
652     vbox=gtk_vbox_new(FALSE, 3);
653     gtk_container_add(GTK_CONTAINER(ss->win), vbox);
654     gtk_container_set_border_width(GTK_CONTAINER(vbox), 12);
655
656     main_nb = gtk_notebook_new();
657     gtk_box_pack_start(GTK_BOX(vbox), main_nb, TRUE, TRUE, 0);
658
659     /* We must display TOP LEVEL Widget before calling init_table() */
660     gtk_widget_show_all(ss->win);
661
662     /* Errors */
663     temp_page = gtk_vbox_new(FALSE, 6);
664     ss->error_label = gtk_label_new("Errors: 0/y");
665     gtk_widget_show(ss->error_label);
666     hbox = gtk_hbox_new(FALSE, 3);
667     gtk_container_add(GTK_CONTAINER(hbox), ss->error_label);
668     gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), temp_page, hbox);
669     init_error_table(&ss->error_table, 0, temp_page);
670
671     /* Warnings */
672     temp_page = gtk_vbox_new(FALSE, 6);
673     ss->warn_label = gtk_label_new("Warnings: 0/y");
674     gtk_widget_show(ss->warn_label);
675     hbox = gtk_hbox_new(FALSE, 3);
676     gtk_container_add(GTK_CONTAINER(hbox), ss->warn_label);
677     gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), temp_page, hbox);
678     init_error_table(&ss->warn_table, 0, temp_page);
679
680     /* Notes */
681     temp_page = gtk_vbox_new(FALSE, 6);
682     ss->note_label = gtk_label_new("Notes: 0/y");
683     gtk_widget_show(ss->note_label);
684     hbox = gtk_hbox_new(FALSE, 3);
685     gtk_container_add(GTK_CONTAINER(hbox), ss->note_label);
686     gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), temp_page, hbox);
687     init_error_table(&ss->note_table, 0, temp_page);
688
689     /* Chat */
690     temp_page = gtk_vbox_new(FALSE, 6);
691     ss->chat_label = gtk_label_new("Chats: 0/y");
692     gtk_widget_show(ss->chat_label);
693     hbox = gtk_hbox_new(FALSE, 3);
694     gtk_container_add(GTK_CONTAINER(hbox), ss->chat_label);
695     gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), temp_page, hbox);
696     init_error_table(&ss->chat_table, 0, temp_page);
697
698     /* Details */
699     temp_page = gtk_vbox_new(FALSE, 6);
700     ss->all_label = gtk_label_new("Details: 0");
701     gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), temp_page, ss->all_label);
702
703     etd = expert_dlg_new_table();
704     etd->label=gtk_label_new("Please wait ...");
705     gtk_misc_set_alignment(GTK_MISC(etd->label), 0.0f, 0.5f);
706
707     etd->win=ss->win;
708     expert_dlg_init_table(etd, temp_page);
709
710     /* Add tap listener functions for expert details, From expert_dlg.c*/
711     error_string=register_tap_listener("expert", etd, NULL /* fstring */,
712                                        TL_REQUIRES_PROTO_TREE,
713                                        expert_dlg_reset,
714                                        expert_dlg_packet,
715                                        expert_dlg_draw);
716     if(error_string){
717         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", error_string->str);
718         g_string_free(error_string, TRUE);
719         g_free(etd);
720         return;
721     }
722
723     g_signal_connect(etd->win, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
724     g_signal_connect(etd->win, "destroy", G_CALLBACK(expert_dlg_destroy_cb), etd);
725
726     /* Register the tap listener */
727
728     error_string=register_tap_listener("expert", ss, filter, 0, error_reset, error_packet, expert_comp_draw);
729     if(error_string){
730         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", error_string->str);
731         g_string_free(error_string, TRUE);
732         g_free(ss);
733         return;
734     }
735
736     /* Button row. */
737     bbox = dlg_button_row_new(GTK_STOCK_CLOSE, GTK_STOCK_HELP, NULL);
738     gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
739
740     close_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE);
741     window_set_cancel_button(ss->win, close_bt, window_cancel_button_cb);
742
743     help_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_HELP);
744     g_signal_connect(help_bt, "clicked", G_CALLBACK(topic_cb), (gpointer)HELP_EXPERT_INFO_DIALOG);
745     gtk_widget_set_tooltip_text (help_bt, "Show topic specific help");
746
747     g_signal_connect(ss->win, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
748     g_signal_connect(ss->win, "destroy", G_CALLBACK(win_destroy_cb), ss);
749
750     gtk_widget_show_all(ss->win);
751     window_present(ss->win);
752
753     /*
754      * At least at present, the only information the tap listener appears
755      * to care about is available regardless of whether the protocol tree
756      * is being built, so we don't appear to need to have the protocol
757      * tree built.
758      *
759      * This means we can use cf_retap_packets(), even though it will only
760      * build the protocol tree if at least one tap has a filter in place.
761      * cf_retap_packets() is faster than cf_redissect_packets(), as it
762      * assumes we didn't change anything that would cause any packets to
763      * dissect differently, and thus doesn't redo the packet display.
764      */
765     cf_retap_packets(&cfile);
766
767     /* This will bring up the progress bar
768      * Put our window back in front
769      */
770     gdk_window_raise(ss->win->window);
771     /* Set the lable text */
772     expert_comp_draw(ss);
773 }
774
775 void
776 expert_comp_dlg_launch(void)
777 {
778     if (expert_comp_dlg_w) {
779         reactivate_window(expert_comp_dlg_w);
780     } else {
781         expert_comp_init("", NULL);
782     }
783 }
784
785 void
786 register_tap_listener_expert_comp(void)
787 {
788     register_stat_cmd_arg("expert_comp", expert_comp_init,NULL);
789 #ifdef MAIN_MENU_USE_UIMANAGER
790 #else
791     register_stat_menu_item_stock("Expert Info _Composite",
792         REGISTER_ANALYZE_GROUP_UNSORTED, WIRESHARK_STOCK_EXPERT_INFO,
793         expert_comp_dlg_launch, NULL, NULL, NULL);
794 #endif
795 }