Add the ability to push and pop messages in to and out of the welcome
[obnox/wireshark/wip.git] / gtk / main_statusbar.c
1 /* main_statusbar.c
2  *
3  * $Id$
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  */
23
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #ifdef HAVE_UNISTD_H
30 #include <unistd.h>
31 #endif
32
33 #include <gtk/gtk.h>
34
35 #include <epan/epan.h>
36 #include <epan/filesystem.h>
37 #include <epan/epan_dissect.h>
38 #include <epan/expert.h>
39 #include <epan/prefs.h>
40
41 #include "../cfile.h"
42 #include "../file.h"
43 #include "../capture_opts.h"
44 #include "../capture_ui_utils.h"
45 #ifdef HAVE_LIBPCAP
46 #include "../capture.h"
47 #endif
48
49 #include "gtk/recent.h"
50 #include "gtk/main.h"
51 #include "gtk/main_statusbar.h"
52 #include "gtk/main_statusbar_private.h"
53 #include "gtk/gui_utils.h"
54 #include "gtk/gtkglobals.h"
55 #include "gtk/expert_comp_dlg.h"
56 #include "gtk/profile_dlg.h"
57 #include "gtk/main_welcome.h"
58
59 #include "../image/expert_error.xpm"
60 #include "../image/expert_warn.xpm"
61 #include "../image/expert_note.xpm"
62 #include "../image/expert_chat.xpm"
63 #include "../image/expert_none.xpm"
64
65 /*
66  * The order below defines the priority of info bar contexts.
67  */
68 typedef enum {
69     STATUS_LEVEL_MAIN,
70     STATUS_LEVEL_FILE,
71     STATUS_LEVEL_FILTER,
72     STATUS_LEVEL_HELP,
73     NUM_STATUS_LEVELS
74 } status_level_e;
75
76
77 #ifdef HAVE_LIBPCAP
78 #define DEF_READY_MESSAGE " Ready to load or capture"
79 #else
80 #define DEF_READY_MESSAGE " Ready to load file"
81 #endif
82
83
84 static GtkWidget    *status_pane_left, *status_pane_right;
85 static GtkWidget    *info_bar, *packets_bar, *profile_bar, *profile_bar_event;
86 static GtkWidget    *expert_info_error, *expert_info_warn, *expert_info_note;
87 static GtkWidget    *expert_info_chat, *expert_info_none;
88
89 static guint        main_ctx, file_ctx, help_ctx, filter_ctx, packets_ctx, profile_ctx;
90 static guint        status_levels[NUM_STATUS_LEVELS];
91 static gchar        *packets_str = NULL;
92 static gchar        *profile_str = NULL;
93
94
95 static void info_bar_new(void);
96 static void packets_bar_new(void);
97 static void profile_bar_new(void);
98 static void status_expert_new(void);
99
100
101
102 /*
103  * Push a message referring to file access onto the statusbar.
104  */
105 static void
106 statusbar_push_file_msg(const gchar *msg)
107 {
108     int i;
109
110     /*g_warning("statusbar_push: %s", msg);*/
111     for (i = STATUS_LEVEL_FILE + 1; i < NUM_STATUS_LEVELS; i++) {
112         if (status_levels[i])
113             return;
114     }
115     status_levels[STATUS_LEVEL_FILE]++;
116     gtk_statusbar_push(GTK_STATUSBAR(info_bar), file_ctx, msg);
117 }
118
119 /*
120  * Pop a message referring to file access off the statusbar.
121  */
122 static void
123 statusbar_pop_file_msg(void)
124 {
125     /*g_warning("statusbar_pop");*/
126     if (status_levels[STATUS_LEVEL_FILE] > 0) {
127         status_levels[STATUS_LEVEL_FILE]--;
128     }
129     gtk_statusbar_pop(GTK_STATUSBAR(info_bar), file_ctx);
130 }
131
132 /*
133  * Push a message referring to the currently-selected field onto the statusbar.
134  */
135 void
136 statusbar_push_field_msg(const gchar *msg)
137 {
138     int i;
139
140     for (i = STATUS_LEVEL_HELP + 1; i < NUM_STATUS_LEVELS; i++) {
141         if (status_levels[i])
142             return;
143     }
144     status_levels[STATUS_LEVEL_HELP]++;
145
146     gtk_statusbar_push(GTK_STATUSBAR(info_bar), help_ctx, msg);
147 }
148
149 /*
150  * Pop a message referring to the currently-selected field off the statusbar.
151  */
152 void
153 statusbar_pop_field_msg(void)
154 {
155     if (status_levels[STATUS_LEVEL_HELP] > 0) {
156         status_levels[STATUS_LEVEL_HELP]--;
157     }
158     gtk_statusbar_pop(GTK_STATUSBAR(info_bar), help_ctx);
159 }
160
161 /*
162  * Push a message referring to the current filter onto the statusbar.
163  */
164 void
165 statusbar_push_filter_msg(const gchar *msg)
166 {
167     int i;
168
169     for (i = STATUS_LEVEL_FILTER + 1; i < NUM_STATUS_LEVELS; i++) {
170         if (status_levels[i])
171             return;
172     }
173     status_levels[STATUS_LEVEL_FILTER]++;
174
175     gtk_statusbar_push(GTK_STATUSBAR(info_bar), filter_ctx, msg);
176 }
177
178 /*
179  * Pop a message referring to the current filter off the statusbar.
180  */
181 void
182 statusbar_pop_filter_msg(void)
183 {
184     if (status_levels[STATUS_LEVEL_FILTER] > 0) {
185         status_levels[STATUS_LEVEL_FILTER]--;
186     }
187     gtk_statusbar_pop(GTK_STATUSBAR(info_bar), filter_ctx);
188 }
189
190
191 GtkWidget *
192 statusbar_new(void)
193 {
194     GtkWidget *status_hbox;
195
196     /* Sstatus hbox */
197     status_hbox = gtk_hbox_new(FALSE, 1);
198     gtk_container_set_border_width(GTK_CONTAINER(status_hbox), 0);
199
200     /* info (main) statusbar */
201     info_bar_new();
202
203     /* packets statusbar */
204     packets_bar_new();
205
206     /* profile statusbar */
207     profile_bar_new();
208
209     /* expert info indicator */
210     status_expert_new();
211
212     /* Pane for the statusbar */
213     status_pane_left = gtk_hpaned_new();
214     gtk_widget_show(status_pane_left);
215     status_pane_right = gtk_hpaned_new();
216     gtk_widget_show(status_pane_right);
217
218     return status_hbox;
219 }
220
221 void
222 statusbar_load_window_geometry(void)
223 {
224     if (recent.has_gui_geometry_status_pane && recent.gui_geometry_status_pane_left)
225         gtk_paned_set_position(GTK_PANED(status_pane_left), recent.gui_geometry_status_pane_left);
226     if (recent.has_gui_geometry_status_pane && recent.gui_geometry_status_pane_right)
227         gtk_paned_set_position(GTK_PANED(status_pane_right), recent.gui_geometry_status_pane_right);
228 }
229
230 void
231 statusbar_save_window_geometry(void)
232 {
233     recent.gui_geometry_status_pane_left    = gtk_paned_get_position(GTK_PANED(status_pane_left));
234     recent.gui_geometry_status_pane_right   = gtk_paned_get_position(GTK_PANED(status_pane_right));
235 }
236
237
238 /*
239  * Helper for statusbar_widgets_emptying()
240  */
241 static void
242 foreach_remove_a_child(GtkWidget *widget, gpointer data) {
243     gtk_container_remove(GTK_CONTAINER(data), widget);
244 }
245
246 void
247 statusbar_widgets_emptying(GtkWidget *statusbar)
248 {
249     g_object_ref(G_OBJECT(info_bar));
250     g_object_ref(G_OBJECT(packets_bar));
251     g_object_ref(G_OBJECT(profile_bar));
252     g_object_ref(G_OBJECT(profile_bar_event));
253     g_object_ref(G_OBJECT(status_pane_left));
254     g_object_ref(G_OBJECT(status_pane_right));
255     g_object_ref(G_OBJECT(expert_info_error));
256     g_object_ref(G_OBJECT(expert_info_warn));
257     g_object_ref(G_OBJECT(expert_info_note));
258     g_object_ref(G_OBJECT(expert_info_chat));
259     g_object_ref(G_OBJECT(expert_info_none));
260
261     /* empty all containers participating */
262     gtk_container_foreach(GTK_CONTAINER(statusbar),     foreach_remove_a_child, statusbar);
263     gtk_container_foreach(GTK_CONTAINER(status_pane_left),   foreach_remove_a_child, status_pane_left);
264     gtk_container_foreach(GTK_CONTAINER(status_pane_right),   foreach_remove_a_child, status_pane_right);
265 }
266
267 void
268 statusbar_widgets_pack(GtkWidget *statusbar)
269 {
270     gtk_box_pack_start(GTK_BOX(statusbar), expert_info_error, FALSE, FALSE, 0);
271     gtk_box_pack_start(GTK_BOX(statusbar), expert_info_warn, FALSE, FALSE, 0);
272     gtk_box_pack_start(GTK_BOX(statusbar), expert_info_note, FALSE, FALSE, 0);
273     gtk_box_pack_start(GTK_BOX(statusbar), expert_info_chat, FALSE, FALSE, 0);
274     gtk_box_pack_start(GTK_BOX(statusbar), expert_info_none, FALSE, FALSE, 0);
275     gtk_box_pack_start(GTK_BOX(statusbar), status_pane_left, TRUE, TRUE, 0);
276     gtk_paned_pack1(GTK_PANED(status_pane_left), info_bar, FALSE, FALSE);
277     gtk_paned_pack2(GTK_PANED(status_pane_left), status_pane_right, TRUE, FALSE);
278     gtk_paned_pack1(GTK_PANED(status_pane_right), packets_bar, TRUE, FALSE);
279     gtk_paned_pack2(GTK_PANED(status_pane_right), profile_bar_event, FALSE, FALSE);
280 }
281
282 void
283 statusbar_widgets_show_or_hide(GtkWidget *statusbar)
284 {
285     /*
286      * Show the status hbox if either:
287      *
288      *    1) we're showing the filter toolbar and we want it in the status
289      *       line
290      *
291      * or
292      *
293      *    2) we're showing the status bar.
294      */
295     if ((recent.filter_toolbar_show && prefs.filter_toolbar_show_in_statusbar) ||
296          recent.statusbar_show) {
297         gtk_widget_show(statusbar);
298     } else {
299         gtk_widget_hide(statusbar);
300     }
301
302     if (recent.statusbar_show) {
303         gtk_widget_show(status_pane_left);
304     } else {
305         gtk_widget_hide(status_pane_left);
306     }
307 }
308
309
310 static void
311 info_bar_new(void)
312 {
313     int i;
314
315     /* tip: tooltips don't work on statusbars! */
316     info_bar = gtk_statusbar_new();
317     main_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "main");
318     file_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "file");
319     help_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "help");
320     filter_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "filter");
321     gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(info_bar), FALSE);
322     gtk_statusbar_push(GTK_STATUSBAR(info_bar), main_ctx, DEF_READY_MESSAGE);
323
324     for (i = 0; i < NUM_STATUS_LEVELS; i++) {
325         status_levels[i] = 0;
326     }
327
328     gtk_widget_show(info_bar);
329 }
330
331 static void
332 packets_bar_new(void)
333 {
334     /* tip: tooltips don't work on statusbars! */
335     packets_bar = gtk_statusbar_new();
336     packets_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(packets_bar), "packets");
337     packets_bar_update();
338     gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(packets_bar), FALSE);
339
340     gtk_widget_show(packets_bar);
341 }
342
343 static void
344 profile_bar_new(void)
345 {
346     GtkTooltips   *tooltips;
347
348     tooltips = gtk_tooltips_new();
349
350     profile_bar_event = gtk_event_box_new();
351     profile_bar = gtk_statusbar_new();
352     gtk_container_add(GTK_CONTAINER(profile_bar_event), profile_bar);
353     g_signal_connect(profile_bar_event, "button_press_event", G_CALLBACK(profile_show_popup_cb), NULL);
354     profile_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(profile_bar), "profile");
355     gtk_tooltips_set_tip (tooltips, profile_bar_event,
356                           "Click to change configuration profile", NULL);
357     profile_bar_update();
358
359     gtk_widget_show(profile_bar);
360     gtk_widget_show(profile_bar_event);
361 }
362
363
364 /*
365  * update the packets statusbar to the current values
366  */
367 void 
368 packets_bar_update(void)
369 {
370
371     if(packets_bar) {
372         /* remove old status */
373         if(packets_str) {
374             g_free(packets_str);
375             gtk_statusbar_pop(GTK_STATUSBAR(packets_bar), packets_ctx);
376         }
377
378         /* do we have any packets? */
379         if(cfile.count) {
380             if(cfile.drops_known) {
381                 packets_str = g_strdup_printf(" Packets: %u Displayed: %u Marked: %u Dropped: %u",
382                     cfile.count, cfile.displayed_count, cfile.marked_count, cfile.drops);
383             } else {
384                 packets_str = g_strdup_printf(" Packets: %u Displayed: %u Marked: %u",
385                     cfile.count, cfile.displayed_count, cfile.marked_count);
386             }
387         } else {
388             packets_str = g_strdup(" No Packets");
389         }
390         gtk_statusbar_push(GTK_STATUSBAR(packets_bar), packets_ctx, packets_str);
391     }
392 }
393
394 /*
395  * update the packets statusbar to the current values
396  */
397 void
398 profile_bar_update(void)
399 {
400     if (profile_bar) {
401         /* remove old status */
402         if(profile_str) {
403             g_free(profile_str);
404             gtk_statusbar_pop(GTK_STATUSBAR(profile_bar), profile_ctx);
405         }
406
407         profile_str = g_strdup_printf (" Profile: %s", get_profile_name ());
408
409         gtk_statusbar_push(GTK_STATUSBAR(profile_bar), profile_ctx, profile_str);
410     }
411 }
412
413
414 static void
415 status_expert_new(void)
416 {
417     GtkWidget *expert_image;
418     GtkTooltips   *tooltips;
419
420     tooltips = gtk_tooltips_new();
421
422     expert_image = xpm_to_widget_from_parent(top_level, expert_error_xpm);
423     gtk_tooltips_set_tip(tooltips, expert_image, "ERROR is the highest expert info level", NULL);
424     gtk_widget_show(expert_image);
425     expert_info_error = gtk_event_box_new();
426     gtk_container_add(GTK_CONTAINER(expert_info_error), expert_image);
427     g_signal_connect(expert_info_error, "button_press_event", G_CALLBACK(expert_comp_dlg_cb), NULL);
428
429     expert_image = xpm_to_widget_from_parent(top_level, expert_warn_xpm);
430     gtk_tooltips_set_tip(tooltips, expert_image, "WARNING is the highest expert info level", NULL);
431     gtk_widget_show(expert_image);
432     expert_info_warn = gtk_event_box_new();
433     gtk_container_add(GTK_CONTAINER(expert_info_warn), expert_image);
434     g_signal_connect(expert_info_warn, "button_press_event", G_CALLBACK(expert_comp_dlg_cb), NULL);
435
436     expert_image = xpm_to_widget_from_parent(top_level, expert_note_xpm);
437     gtk_tooltips_set_tip(tooltips, expert_image, "NOTE is the highest expert info level", NULL);
438     gtk_widget_show(expert_image);
439     expert_info_note = gtk_event_box_new();
440     gtk_container_add(GTK_CONTAINER(expert_info_note), expert_image);
441     g_signal_connect(expert_info_note, "button_press_event", G_CALLBACK(expert_comp_dlg_cb), NULL);
442
443     expert_image = xpm_to_widget_from_parent(top_level, expert_chat_xpm);
444     gtk_tooltips_set_tip(tooltips, expert_image, "CHAT is the highest expert info level", NULL);
445     gtk_widget_show(expert_image);
446     expert_info_chat = gtk_event_box_new();
447     gtk_container_add(GTK_CONTAINER(expert_info_chat), expert_image);
448     g_signal_connect(expert_info_chat, "button_press_event", G_CALLBACK(expert_comp_dlg_cb), NULL);
449
450     expert_image = xpm_to_widget_from_parent(top_level, expert_none_xpm);
451     gtk_tooltips_set_tip(tooltips, expert_image, "No expert info", NULL);
452     gtk_widget_show(expert_image);
453     expert_info_none = gtk_event_box_new();
454     gtk_container_add(GTK_CONTAINER(expert_info_none), expert_image);
455     g_signal_connect(expert_info_none, "button_press_event", G_CALLBACK(expert_comp_dlg_cb), NULL);
456     gtk_widget_show(expert_info_none);
457 }
458
459 static void
460 status_expert_hide(void)
461 {
462     /* reset expert info indicator */
463     gtk_widget_hide(expert_info_error);
464     gtk_widget_hide(expert_info_warn);
465     gtk_widget_hide(expert_info_note);
466     gtk_widget_hide(expert_info_chat);
467     gtk_widget_hide(expert_info_none);
468 }
469
470 void
471 status_expert_update(void)
472 {
473     status_expert_hide();
474
475     switch(expert_get_highest_severity()) {
476         case(PI_ERROR):
477         gtk_widget_show(expert_info_error);
478         break;
479         case(PI_WARN):
480         gtk_widget_show(expert_info_warn);
481         break;
482         case(PI_NOTE):
483         gtk_widget_show(expert_info_note);
484         break;
485         case(PI_CHAT):
486         gtk_widget_show(expert_info_chat);
487         break;
488         default:
489         gtk_widget_show(expert_info_none);
490         break;
491     }
492 }
493
494 static void
495 statusbar_set_filename(const char *file_name, gint64 file_length, nstime_t *file_elapsed_time)
496 {
497   gchar       *size_str;
498   gchar       *status_msg;
499
500   /* expert info indicator */
501   status_expert_update();
502
503   /* statusbar */
504   /* convert file size */
505   if (file_length/1024/1024 > 10) {
506     size_str = g_strdup_printf("%" G_GINT64_MODIFIER "d MB", file_length/1024/1024);
507   } else if (file_length/1024 > 10) {
508     size_str = g_strdup_printf("%" G_GINT64_MODIFIER "d KB", file_length/1024);
509   } else {
510     size_str = g_strdup_printf("%" G_GINT64_MODIFIER "d Bytes", file_length);
511   }
512
513   status_msg = g_strdup_printf(" File: \"%s\" %s %02lu:%02lu:%02lu",
514     (file_name) ? file_name : "", size_str,
515     (long)file_elapsed_time->secs/3600,
516     (long)file_elapsed_time->secs%3600/60,
517     (long)file_elapsed_time->secs%60);
518   g_free(size_str);
519   statusbar_push_file_msg(status_msg);
520   g_free(status_msg);
521 }
522
523
524 static void
525 statusbar_cf_file_closing_cb(capture_file *cf _U_)
526 {
527     /* Clear any file-related status bar messages.
528        XXX - should be "clear *ALL* file-related status bar messages;
529        will there ever be more than one on the stack? */
530     statusbar_pop_file_msg();
531
532     /* reset expert info indicator */
533     status_expert_hide();
534     gtk_widget_show(expert_info_none);
535 }
536
537
538 static void
539 statusbar_cf_file_closed_cb(capture_file *cf _U_)
540 {
541   /* go back to "No packets" */
542   packets_bar_update();
543 }
544
545
546 static void
547 statusbar_cf_file_read_start_cb(capture_file *cf)
548 {
549   const gchar *name_ptr;
550   gchar       *load_msg;
551
552   /* Ensure we pop any previous loaded filename */
553   statusbar_pop_file_msg();
554
555   name_ptr = get_basename(cf->filename);
556
557   load_msg = g_strdup_printf(" Loading: %s", name_ptr);
558   statusbar_push_file_msg(load_msg);
559   g_free(load_msg);
560 }
561
562
563 static void
564 statusbar_cf_file_read_finished_cb(capture_file *cf)
565 {
566     statusbar_pop_file_msg();
567     statusbar_set_filename(cf->filename, cf->f_datalen, &(cf->elapsed_time));
568 }
569
570
571 #ifdef HAVE_LIBPCAP
572 static void
573 statusbar_capture_prepared_cb(capture_options *capture_opts _U_)
574 {
575     gchar *msg = " Waiting for capture input data ...";
576     statusbar_push_file_msg(msg);
577     welcome_header_push_msg(msg);
578 }
579
580 static void
581 statusbar_capture_update_started_cb(capture_options *capture_opts)
582 {
583     gchar *capture_msg;
584
585
586     statusbar_pop_file_msg();
587     welcome_header_pop_msg();
588
589     if(capture_opts->iface) {
590         capture_msg = g_strdup_printf(" %s: <live capture in progress> to file: %s",
591                                       get_iface_description(capture_opts),
592                                       (capture_opts->save_file) ? capture_opts->save_file : "");
593     } else {
594         capture_msg = g_strdup_printf(" <live capture in progress> to file: %s",
595             (capture_opts->save_file) ? capture_opts->save_file : "");
596     }
597
598     statusbar_push_file_msg(capture_msg);
599
600     g_free(capture_msg);
601 }
602
603 static void
604 statusbar_capture_update_continue_cb(capture_options *capture_opts)
605 {
606     capture_file *cf = capture_opts->cf;
607     gchar *capture_msg;
608
609
610     status_expert_update();
611
612     statusbar_pop_file_msg();
613
614     if (cf->f_datalen/1024/1024 > 10) {
615         capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %" G_GINT64_MODIFIER "d MB",
616                                       get_iface_description(capture_opts),
617                                       capture_opts->save_file,
618                                       cf->f_datalen/1024/1024);
619     } else if (cf->f_datalen/1024 > 10) {
620         capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %" G_GINT64_MODIFIER "d KB",
621                                       get_iface_description(capture_opts),
622                                       capture_opts->save_file,
623                                       cf->f_datalen/1024);
624     } else {
625         capture_msg = g_strdup_printf(" %s: <live capture in progress> File: %s %" G_GINT64_MODIFIER "d Bytes",
626                                       get_iface_description(capture_opts),
627                                       capture_opts->save_file,
628                                       cf->f_datalen);
629     }
630
631     statusbar_push_file_msg(capture_msg);
632 }
633
634 static void
635 statusbar_capture_update_finished_cb(capture_options *capture_opts)
636 {
637     capture_file *cf = capture_opts->cf;
638
639     /* Pop the "<live capture in progress>" message off the status bar. */
640     statusbar_pop_file_msg();
641     statusbar_set_filename(cf->filename, cf->f_datalen, &(cf->elapsed_time));
642 }
643
644 static void
645 statusbar_capture_fixed_started_cb(capture_options *capture_opts)
646 {
647     gchar *capture_msg;
648
649
650     statusbar_pop_file_msg();
651
652     capture_msg = g_strdup_printf(" %s: <live capture in progress> to file: %s",
653                                   get_iface_description(capture_opts),
654                                   (capture_opts->save_file) ? capture_opts->save_file : "");
655
656     statusbar_push_file_msg(capture_msg);
657     gtk_statusbar_push(GTK_STATUSBAR(packets_bar), packets_ctx, " Packets: 0");
658
659     g_free(capture_msg);
660 }
661
662 static void
663 statusbar_capture_fixed_continue_cb(capture_options *capture_opts)
664 {
665     capture_file *cf = capture_opts->cf;
666     gchar *capture_msg;
667
668
669     gtk_statusbar_pop(GTK_STATUSBAR(packets_bar), packets_ctx);
670     capture_msg = g_strdup_printf(" Packets: %u", cf_get_packet_count(cf));
671     gtk_statusbar_push(GTK_STATUSBAR(packets_bar), packets_ctx, capture_msg);
672     g_free(capture_msg);
673 }
674
675
676 static void
677 statusbar_capture_fixed_finished_cb(capture_options *capture_opts _U_)
678 {
679 #if 0
680     capture_file *cf = capture_opts->cf;
681 #endif
682
683     /* Pop the "<live capture in progress>" message off the status bar. */
684     statusbar_pop_file_msg();
685
686     /* Pop the "<capturing>" message off the status bar */
687     gtk_statusbar_pop(GTK_STATUSBAR(packets_bar), packets_ctx);
688 }
689
690 #endif /* HAVE_LIBPCAP */
691
692
693 static void
694 statusbar_cf_field_unselected_cb(capture_file *cf _U_)
695 {
696     statusbar_pop_field_msg();
697 }
698
699 static void
700 statusbar_cf_file_safe_started_cb(gchar * filename)
701 {
702     gchar        *save_msg;
703
704     save_msg = g_strdup_printf(" Saving: %s...", get_basename(filename));
705     statusbar_push_file_msg(save_msg);
706     g_free(save_msg);
707 }
708
709 static void
710 statusbar_cf_file_safe_finished_cb(gpointer data _U_)
711 {
712     /* Pop the "Saving:" message off the status bar. */
713     statusbar_pop_file_msg();
714 }
715
716 static void
717 statusbar_cf_file_safe_failed_cb(gpointer data _U_)
718 {
719     /* Pop the "Saving:" message off the status bar. */
720     statusbar_pop_file_msg();
721 }
722
723
724
725 void
726 statusbar_cf_callback(gint event, gpointer data, gpointer user_data _U_)
727 {
728     switch(event) {
729     case(cf_cb_file_closing):
730         statusbar_cf_file_closing_cb(data);
731         break;
732     case(cf_cb_file_closed):
733         statusbar_cf_file_closed_cb(data);
734         break;
735     case(cf_cb_file_read_start):
736         statusbar_cf_file_read_start_cb(data);
737         break;
738     case(cf_cb_file_read_finished):
739         statusbar_cf_file_read_finished_cb(data);
740         break;
741     case(cf_cb_packet_selected):
742         break;
743     case(cf_cb_packet_unselected):
744         break;
745     case(cf_cb_field_unselected):
746         statusbar_cf_field_unselected_cb(data);
747         break;
748     case(cf_cb_file_safe_started):
749         statusbar_cf_file_safe_started_cb(data);
750         break;
751     case(cf_cb_file_safe_finished):
752         statusbar_cf_file_safe_finished_cb(data);
753         break;
754     case(cf_cb_file_safe_reload_finished):
755         break;
756     case(cf_cb_file_safe_failed):
757         statusbar_cf_file_safe_failed_cb(data);
758         break;
759     default:
760         g_warning("statusbar_cf_callback: event %u unknown", event);
761         g_assert_not_reached();
762     }
763 }
764
765 #ifdef HAVE_LIBPCAP
766 void
767 statusbar_capture_callback(gint event, capture_options *capture_opts,
768                            gpointer user_data _U_)
769 {
770     switch(event) {
771     case(capture_cb_capture_prepared):
772         statusbar_capture_prepared_cb(capture_opts);
773         break;
774     case(capture_cb_capture_update_started):
775         statusbar_capture_update_started_cb(capture_opts);
776         break;
777     case(capture_cb_capture_update_continue):
778         statusbar_capture_update_continue_cb(capture_opts);
779         break;
780     case(capture_cb_capture_update_finished):
781         statusbar_capture_update_finished_cb(capture_opts);
782         break;
783     case(capture_cb_capture_fixed_started):
784         statusbar_capture_fixed_started_cb(capture_opts);
785         break;
786     case(capture_cb_capture_fixed_continue):
787         statusbar_capture_fixed_continue_cb(capture_opts);
788         break;
789     case(capture_cb_capture_fixed_finished):
790         statusbar_capture_fixed_finished_cb(capture_opts);
791         break;
792     case(capture_cb_capture_stopping):
793         /* Beware: this state won't be called, if the capture child
794          * closes the capturing on it's own! */
795         break;
796     default:
797         g_warning("statusbar_capture_callback: event %u unknown", event);
798         g_assert_not_reached();
799     }
800 }
801 #endif