add parameter dcerpc_info to PIDL_dissect_ipv?address()
[wireshark-wip.git] / ui / gtk / main_statusbar.c
blobbc199e197a1ccd9a4b41fea7b97e6e8e2d250d15
1 /* main_statusbar.c
3 * $Id$
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 #include "config.h"
27 #ifdef HAVE_UNISTD_H
28 #include <unistd.h>
29 #endif
31 #include <gtk/gtk.h>
33 #include <epan/epan.h>
34 #include <epan/filesystem.h>
35 #include <epan/epan_dissect.h>
36 #include <epan/expert.h>
37 #include <epan/prefs.h>
39 #include "../cfile.h"
40 #include "../file.h"
41 #ifdef HAVE_LIBPCAP
42 #include "../capture_opts.h"
43 #include "../capture_session.h"
44 #include "../capture_ui_utils.h"
45 #include "../capture.h"
46 #endif
48 #include <wsutil/str_util.h>
50 #include "ui/main_statusbar.h"
51 #include "ui/recent.h"
52 #include "ui/utf8_entities.h"
54 #include "ui/gtk/main.h"
55 #include "ui/gtk/main_statusbar_private.h"
56 #include "ui/gtk/gui_utils.h"
57 #include "ui/gtk/gtkglobals.h"
58 #include "ui/gtk/expert_comp_dlg.h"
59 #include "ui/gtk/profile_dlg.h"
60 #include "ui/gtk/main_welcome.h"
61 #include "ui/gtk/expert_indicators.h"
62 #include "ui/gtk/capture_comment_icons.h"
63 #include "ui/gtk/keys.h"
64 #include "ui/gtk/menus.h"
65 #include "ui/gtk/edit_packet_comment_dlg.h"
68 * The order below defines the priority of info bar contexts.
70 typedef enum {
71 STATUS_LEVEL_MAIN,
72 STATUS_LEVEL_FILE,
73 STATUS_LEVEL_FILTER,
74 STATUS_LEVEL_HELP,
75 NUM_STATUS_LEVELS
76 } status_level_e;
79 #ifdef HAVE_LIBPCAP
80 #define DEF_READY_MESSAGE " Ready to load or capture"
81 #else
82 #define DEF_READY_MESSAGE " Ready to load file"
83 #endif
86 static GtkWidget *status_pane_left, *status_pane_right;
87 static GtkWidget *info_bar, *info_bar_event, *packets_bar, *profile_bar, *profile_bar_event;
88 static GtkWidget *expert_info_error, *expert_info_warn, *expert_info_note;
89 static GtkWidget *expert_info_chat, *expert_info_comment, *expert_info_none;
91 static GtkWidget *capture_comment_none, *capture_comment;
93 static guint main_ctx, file_ctx, help_ctx, filter_ctx, packets_ctx, profile_ctx;
94 static guint status_levels[NUM_STATUS_LEVELS];
95 static GString *packets_str = NULL;
96 static gchar *profile_str = NULL;
99 static void info_bar_new(void);
100 static void packets_bar_new(void);
101 static void profile_bar_new(void);
102 static void status_expert_new(void);
103 static void status_capture_comment_new(void);
105 /* Temporary message timeouts */
106 #define TEMPORARY_MSG_TIMEOUT (7 * 1000)
107 #define TEMPORARY_FLASH_TIMEOUT (1 * 1000)
108 #define TEMPORARY_FLASH_INTERVAL (TEMPORARY_FLASH_TIMEOUT / 4)
109 static gint flash_time;
110 static gboolean flash_highlight = FALSE;
112 static void
113 statusbar_push_file_msg(const gchar *msg_format, ...)
114 G_GNUC_PRINTF(1, 2);
117 * Return TRUE if there are any higher priority status level messages pushed.
118 * Return FALSE otherwise.
120 static gboolean
121 higher_priority_status_level(int level)
123 int i;
125 for (i = level + 1; i < NUM_STATUS_LEVELS; i++) {
126 if (status_levels[i])
127 return TRUE;
129 return FALSE;
133 * Push a formatted message referring to file access onto the statusbar.
135 static void
136 statusbar_push_file_msg(const gchar *msg_format, ...)
138 va_list ap;
139 gchar *msg;
141 /*g_warning("statusbar_push: %s", msg);*/
142 if (higher_priority_status_level(STATUS_LEVEL_FILE))
143 return;
144 status_levels[STATUS_LEVEL_FILE]++;
146 va_start(ap, msg_format);
147 msg = g_strdup_vprintf(msg_format, ap);
148 va_end(ap);
150 gtk_statusbar_push(GTK_STATUSBAR(info_bar), file_ctx, msg);
151 g_free(msg);
155 * Pop a message referring to file access off the statusbar.
157 static void
158 statusbar_pop_file_msg(void)
160 /*g_warning("statusbar_pop");*/
161 if (status_levels[STATUS_LEVEL_FILE] > 0) {
162 status_levels[STATUS_LEVEL_FILE]--;
164 gtk_statusbar_pop(GTK_STATUSBAR(info_bar), file_ctx);
168 * Push a formatted message referring to the currently-selected field onto
169 * the statusbar.
171 void
172 statusbar_push_field_msg(const gchar *msg_format, ...)
174 va_list ap;
175 gchar *msg;
177 if (higher_priority_status_level(STATUS_LEVEL_HELP))
178 return;
179 status_levels[STATUS_LEVEL_HELP]++;
181 va_start(ap, msg_format);
182 msg = g_strdup_vprintf(msg_format, ap);
183 va_end(ap);
185 gtk_statusbar_push(GTK_STATUSBAR(info_bar), help_ctx, msg);
186 g_free(msg);
190 * Pop a message referring to the currently-selected field off the statusbar.
192 void
193 statusbar_pop_field_msg(void)
195 if (status_levels[STATUS_LEVEL_HELP] > 0) {
196 status_levels[STATUS_LEVEL_HELP]--;
198 gtk_statusbar_pop(GTK_STATUSBAR(info_bar), help_ctx);
202 * Push a formatted message referring to the current filter onto the statusbar.
204 void
205 statusbar_push_filter_msg(const gchar *msg_format, ...)
207 va_list ap;
208 gchar *msg;
210 if (higher_priority_status_level(STATUS_LEVEL_FILTER))
211 return;
212 status_levels[STATUS_LEVEL_FILTER]++;
214 va_start(ap, msg_format);
215 msg = g_strdup_vprintf(msg_format, ap);
216 va_end(ap);
218 gtk_statusbar_push(GTK_STATUSBAR(info_bar), filter_ctx, msg);
219 g_free(msg);
223 * Pop a message referring to the current filter off the statusbar.
225 void
226 statusbar_pop_filter_msg(void)
228 if (status_levels[STATUS_LEVEL_FILTER] > 0) {
229 status_levels[STATUS_LEVEL_FILTER]--;
231 gtk_statusbar_pop(GTK_STATUSBAR(info_bar), filter_ctx);
235 * Timeout callbacks for statusbar_push_temporary_msg
237 static gboolean
238 statusbar_remove_temporary_msg(gpointer data)
240 guint msg_id = GPOINTER_TO_UINT(data);
242 gtk_statusbar_remove(GTK_STATUSBAR(info_bar), main_ctx, msg_id);
244 return FALSE;
247 static gboolean
248 statusbar_flash_temporary_msg(gpointer data _U_)
250 gboolean retval = TRUE;
252 if (flash_time > 0) {
253 flash_highlight = !flash_highlight;
254 } else {
255 flash_highlight = FALSE;
256 retval = FALSE;
260 * As of 2.18.3 gtk_drag_highlight just draws a border around the widget
261 * so we can abuse it here.
263 if (flash_highlight) {
264 gtk_drag_highlight(info_bar);
265 } else {
266 gtk_drag_unhighlight(info_bar);
269 flash_time -= TEMPORARY_FLASH_INTERVAL;
271 return retval;
275 * Push a formatted temporary message onto the statusbar.
277 void
278 statusbar_push_temporary_msg(const gchar *msg_format, ...)
280 va_list ap;
281 gchar *msg;
282 guint msg_id;
284 va_start(ap, msg_format);
285 msg = g_strdup_vprintf(msg_format, ap);
286 va_end(ap);
288 msg_id = gtk_statusbar_push(GTK_STATUSBAR(info_bar), main_ctx, msg);
289 g_free(msg);
291 flash_time = TEMPORARY_FLASH_TIMEOUT - 1;
292 g_timeout_add(TEMPORARY_FLASH_INTERVAL, statusbar_flash_temporary_msg, NULL);
294 g_timeout_add(TEMPORARY_MSG_TIMEOUT, statusbar_remove_temporary_msg, GUINT_TO_POINTER(msg_id));
298 GtkWidget *
299 statusbar_new(void)
301 GtkWidget *status_hbox;
303 /* Status hbox */
304 status_hbox = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 1, FALSE);
305 gtk_container_set_border_width(GTK_CONTAINER(status_hbox), 0);
307 /* info (main) statusbar */
308 info_bar_new();
310 /* packets statusbar */
311 packets_bar_new();
313 /* profile statusbar */
314 profile_bar_new();
316 /* expert info indicator */
317 status_expert_new();
319 /* Capture comments indicator */
320 status_capture_comment_new();
322 /* Pane for the statusbar */
323 status_pane_left = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
324 gtk_widget_show(status_pane_left);
325 status_pane_right = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
326 gtk_widget_show(status_pane_right);
328 return status_hbox;
331 void
332 statusbar_load_window_geometry(void)
334 if (recent.has_gui_geometry_status_pane && recent.gui_geometry_status_pane_left)
335 gtk_paned_set_position(GTK_PANED(status_pane_left), recent.gui_geometry_status_pane_left);
336 if (recent.has_gui_geometry_status_pane && recent.gui_geometry_status_pane_right)
337 gtk_paned_set_position(GTK_PANED(status_pane_right), recent.gui_geometry_status_pane_right);
340 void
341 statusbar_save_window_geometry(void)
343 recent.gui_geometry_status_pane_left = gtk_paned_get_position(GTK_PANED(status_pane_left));
344 recent.gui_geometry_status_pane_right = gtk_paned_get_position(GTK_PANED(status_pane_right));
349 * Helper for statusbar_widgets_emptying()
351 static void
352 foreach_remove_a_child(GtkWidget *widget, gpointer data) {
353 gtk_container_remove(GTK_CONTAINER(data), widget);
356 void
357 statusbar_widgets_emptying(GtkWidget *statusbar)
359 g_object_ref(G_OBJECT(info_bar));
360 g_object_ref(G_OBJECT(info_bar_event));
361 g_object_ref(G_OBJECT(packets_bar));
362 g_object_ref(G_OBJECT(profile_bar));
363 g_object_ref(G_OBJECT(profile_bar_event));
364 g_object_ref(G_OBJECT(status_pane_left));
365 g_object_ref(G_OBJECT(status_pane_right));
366 g_object_ref(G_OBJECT(expert_info_error));
367 g_object_ref(G_OBJECT(expert_info_warn));
368 g_object_ref(G_OBJECT(expert_info_note));
369 g_object_ref(G_OBJECT(expert_info_chat));
370 g_object_ref(G_OBJECT(expert_info_comment));
371 g_object_ref(G_OBJECT(expert_info_none));
372 g_object_ref(G_OBJECT(capture_comment));
373 g_object_ref(G_OBJECT(capture_comment_none));
376 /* empty all containers participating */
377 gtk_container_foreach(GTK_CONTAINER(statusbar), foreach_remove_a_child, statusbar);
378 gtk_container_foreach(GTK_CONTAINER(status_pane_left), foreach_remove_a_child, status_pane_left);
379 gtk_container_foreach(GTK_CONTAINER(status_pane_right), foreach_remove_a_child, status_pane_right);
382 void
383 statusbar_widgets_pack(GtkWidget *statusbar)
385 gtk_box_pack_start(GTK_BOX(statusbar), expert_info_error, FALSE, FALSE, 2);
386 gtk_box_pack_start(GTK_BOX(statusbar), expert_info_warn, FALSE, FALSE, 2);
387 gtk_box_pack_start(GTK_BOX(statusbar), expert_info_note, FALSE, FALSE, 2);
388 gtk_box_pack_start(GTK_BOX(statusbar), expert_info_chat, FALSE, FALSE, 2);
389 gtk_box_pack_start(GTK_BOX(statusbar), expert_info_comment, FALSE, FALSE, 2);
390 gtk_box_pack_start(GTK_BOX(statusbar), expert_info_none, FALSE, FALSE, 2);
391 gtk_box_pack_start(GTK_BOX(statusbar), capture_comment, FALSE, FALSE, 2);
392 gtk_box_pack_start(GTK_BOX(statusbar), capture_comment_none, FALSE, FALSE, 2);
393 gtk_box_pack_start(GTK_BOX(statusbar), status_pane_left, TRUE, TRUE, 0);
394 gtk_paned_pack1(GTK_PANED(status_pane_left), info_bar_event, FALSE, FALSE);
395 gtk_paned_pack2(GTK_PANED(status_pane_left), status_pane_right, TRUE, FALSE);
396 gtk_paned_pack1(GTK_PANED(status_pane_right), packets_bar, TRUE, FALSE);
397 gtk_paned_pack2(GTK_PANED(status_pane_right), profile_bar_event, FALSE, FALSE);
400 void
401 statusbar_widgets_show_or_hide(GtkWidget *statusbar)
404 * Show the status hbox if either:
406 * 1) we're showing the filter toolbar and we want it in the status
407 * line
409 * or
411 * 2) we're showing the status bar.
413 if ((recent.filter_toolbar_show && prefs.filter_toolbar_show_in_statusbar) ||
414 recent.statusbar_show) {
415 gtk_widget_show(statusbar);
416 } else {
417 gtk_widget_hide(statusbar);
420 if (recent.statusbar_show) {
421 gtk_widget_show(status_pane_left);
422 } else {
423 gtk_widget_hide(status_pane_left);
428 static void
429 info_bar_new(void)
431 info_bar_event = gtk_event_box_new();
432 info_bar = gtk_statusbar_new();
433 gtk_container_add(GTK_CONTAINER(info_bar_event), info_bar);
434 main_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "main");
435 file_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "file");
436 help_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "help");
437 filter_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "filter");
438 #if !GTK_CHECK_VERSION(3,0,0)
439 gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(info_bar), FALSE);
440 #endif
441 gtk_statusbar_push(GTK_STATUSBAR(info_bar), main_ctx, DEF_READY_MESSAGE);
443 memset(status_levels, 0, sizeof(status_levels));
445 gtk_widget_show(info_bar);
446 gtk_widget_show(info_bar_event);
449 static void
450 packets_bar_new(void)
452 /* tip: tooltips don't work on statusbars! */
453 packets_bar = gtk_statusbar_new();
454 packets_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(packets_bar), "packets");
455 packets_bar_update();
456 #if !GTK_CHECK_VERSION(3,0,0)
457 gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(packets_bar), FALSE);
458 #endif
460 gtk_widget_show(packets_bar);
463 static void
464 profile_bar_new(void)
466 profile_bar_event = gtk_event_box_new();
467 profile_bar = gtk_statusbar_new();
468 gtk_container_add(GTK_CONTAINER(profile_bar_event), profile_bar);
469 g_signal_connect(profile_bar_event, "button_press_event", G_CALLBACK(profile_show_popup_cb), NULL);
470 g_signal_connect(profile_bar_event, "button_press_event", G_CALLBACK(popup_menu_handler),
471 g_object_get_data(G_OBJECT(popup_menu_object), PM_STATUSBAR_PROFILES_KEY));
472 profile_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(profile_bar), "profile");
473 gtk_widget_set_tooltip_text(profile_bar_event, "Click to change configuration profile");
474 profile_bar_update();
475 #if !GTK_CHECK_VERSION(3,0,0)
476 gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(profile_bar), FALSE);
477 #endif
479 gtk_widget_show(profile_bar);
480 gtk_widget_show(profile_bar_event);
485 * Update the packets statusbar to the current values
487 void
488 packets_bar_update(void)
490 if(packets_bar) {
491 /* Remove old status */
492 if(packets_str) {
493 gtk_statusbar_pop(GTK_STATUSBAR(packets_bar), packets_ctx);
494 } else {
495 packets_str = g_string_new ("");
498 /* Do we have any packets? */
499 if(cfile.count) {
500 g_string_printf(packets_str, " Packets: %u " UTF8_MIDDLE_DOT
501 " Displayed: %u (%.1f%%) ",
502 cfile.count,
503 cfile.displayed_count,
504 (100.0 * cfile.displayed_count)/cfile.count);
505 if(cfile.marked_count) {
506 g_string_append_printf(packets_str, " " UTF8_MIDDLE_DOT " Marked: %u (%.1f%%)",
507 cfile.marked_count, (100.0 * cfile.marked_count)/cfile.count);
509 if(cfile.drops_known) {
510 g_string_append_printf(packets_str, " " UTF8_MIDDLE_DOT " Dropped: %u (%.1f%%)",
511 cfile.drops, (100.0 * cfile.drops)/cfile.count);
513 if(cfile.ignored_count) {
514 g_string_append_printf(packets_str, " " UTF8_MIDDLE_DOT " Ignored: %u (%.1f%%)",
515 cfile.ignored_count, (100.0 * cfile.ignored_count)/cfile.count);
517 if(!cfile.is_tempfile){
518 /* Loading an existing file */
519 gulong computed_elapsed = cf_get_computed_elapsed(&cfile);
520 g_string_append_printf(packets_str, " " UTF8_MIDDLE_DOT " Load time: %lu:%02lu.%03lu",
521 computed_elapsed/60000,
522 computed_elapsed%60000/1000,
523 computed_elapsed%1000);
525 } else {
526 g_string_printf(packets_str, " No Packets");
528 gtk_statusbar_push(GTK_STATUSBAR(packets_bar), packets_ctx, packets_str->str);
533 * Update the packets statusbar to the current values
535 void
536 profile_bar_update(void)
538 if (profile_bar) {
539 /* remove old status */
540 if(profile_str) {
541 g_free(profile_str);
542 gtk_statusbar_pop(GTK_STATUSBAR(profile_bar), profile_ctx);
545 profile_str = g_strdup_printf (" Profile: %s", get_profile_name ());
546 gtk_statusbar_push(GTK_STATUSBAR(profile_bar), profile_ctx, profile_str);
548 set_menus_for_profiles(is_default_profile());
552 static gboolean
553 expert_comp_dlg_event_cb(GtkWidget *w _U_, GdkEventButton *event _U_, gpointer user_data _U_)
555 expert_comp_dlg_launch();
556 return TRUE;
559 static gboolean
560 edit_capture_comment_dlg_event_cb(GtkWidget *w _U_, GdkEventButton *event _U_, gpointer user_data _U_)
562 edit_capture_comment_dlg_launch();
563 return TRUE;
566 static void
567 status_expert_new(void)
569 GtkWidget *expert_image;
571 expert_image = pixbuf_to_widget(expert_error_pb_data);
572 gtk_widget_set_tooltip_text(expert_image, "ERROR is the highest expert info level");
573 gtk_widget_show(expert_image);
574 expert_info_error = gtk_event_box_new();
575 gtk_container_add(GTK_CONTAINER(expert_info_error), expert_image);
576 g_signal_connect(expert_info_error, "button_press_event", G_CALLBACK(expert_comp_dlg_event_cb), NULL);
578 expert_image = pixbuf_to_widget(expert_warn_pb_data);
579 gtk_widget_set_tooltip_text(expert_image, "WARNING is the highest expert info level");
580 gtk_widget_show(expert_image);
581 expert_info_warn = gtk_event_box_new();
582 gtk_container_add(GTK_CONTAINER(expert_info_warn), expert_image);
583 g_signal_connect(expert_info_warn, "button_press_event", G_CALLBACK(expert_comp_dlg_event_cb), NULL);
585 expert_image = pixbuf_to_widget(expert_note_pb_data);
586 gtk_widget_set_tooltip_text(expert_image, "NOTE is the highest expert info level");
587 gtk_widget_show(expert_image);
588 expert_info_note = gtk_event_box_new();
589 gtk_container_add(GTK_CONTAINER(expert_info_note), expert_image);
590 g_signal_connect(expert_info_note, "button_press_event", G_CALLBACK(expert_comp_dlg_event_cb), NULL);
592 expert_image = pixbuf_to_widget(expert_chat_pb_data);
593 gtk_widget_set_tooltip_text(expert_image, "CHAT is the highest expert info level");
594 gtk_widget_show(expert_image);
595 expert_info_chat = gtk_event_box_new();
596 gtk_container_add(GTK_CONTAINER(expert_info_chat), expert_image);
597 g_signal_connect(expert_info_chat, "button_press_event", G_CALLBACK(expert_comp_dlg_event_cb), NULL);
599 expert_image = gtk_image_new_from_stock(GTK_STOCK_YES, GTK_ICON_SIZE_MENU);
600 gtk_widget_set_tooltip_text(expert_image, "COMMENT is the highest expert info level");
601 gtk_widget_show(expert_image);
602 expert_info_comment = gtk_event_box_new();
603 gtk_container_add(GTK_CONTAINER(expert_info_comment), expert_image);
604 g_signal_connect(expert_info_comment, "button_press_event", G_CALLBACK(expert_comp_dlg_event_cb), NULL);
606 expert_image = pixbuf_to_widget(expert_none_pb_data);
607 gtk_widget_set_tooltip_text(expert_image, "No expert info");
608 gtk_widget_show(expert_image);
609 expert_info_none = gtk_event_box_new();
610 gtk_container_add(GTK_CONTAINER(expert_info_none), expert_image);
611 g_signal_connect(expert_info_none, "button_press_event", G_CALLBACK(expert_comp_dlg_event_cb), NULL);
614 static void
615 status_expert_hide(void)
617 /* reset expert info indicator */
618 gtk_widget_hide(expert_info_error);
619 gtk_widget_hide(expert_info_warn);
620 gtk_widget_hide(expert_info_note);
621 gtk_widget_hide(expert_info_chat);
622 gtk_widget_hide(expert_info_comment);
623 gtk_widget_hide(expert_info_none);
626 void
627 status_expert_update(void)
629 status_expert_hide();
631 switch(expert_get_highest_severity()) {
632 case(PI_ERROR):
633 gtk_widget_show(expert_info_error);
634 break;
635 case(PI_WARN):
636 gtk_widget_show(expert_info_warn);
637 break;
638 case(PI_NOTE):
639 gtk_widget_show(expert_info_note);
640 break;
641 case(PI_CHAT):
642 gtk_widget_show(expert_info_chat);
643 break;
644 case(PI_COMMENT):
645 gtk_widget_show(expert_info_comment);
646 break;
647 default:
648 gtk_widget_show(expert_info_none);
649 break;
653 static void
654 status_capture_comment_new(void)
656 GtkWidget *comment_image;
658 comment_image = pixbuf_to_widget(capture_comment_update_pb_data);
659 gtk_widget_set_tooltip_text(comment_image, "Read or edit the comment for this capture file");
660 gtk_widget_show(comment_image);
661 capture_comment = gtk_event_box_new();
662 gtk_container_add(GTK_CONTAINER(capture_comment), comment_image);
663 g_signal_connect(capture_comment, "button_press_event", G_CALLBACK(edit_capture_comment_dlg_event_cb), NULL);
665 comment_image = pixbuf_to_widget(capture_comment_add_pb_data);
666 gtk_widget_set_tooltip_text(comment_image, "Add a comment to this capture file");
667 gtk_widget_show(comment_image);
668 capture_comment_none = gtk_event_box_new();
669 gtk_container_add(GTK_CONTAINER(capture_comment_none), comment_image);
670 g_signal_connect(capture_comment_none, "button_press_event", G_CALLBACK(edit_capture_comment_dlg_event_cb), NULL);
672 /* comment_image = pixbuf_to_widget(capture_comment_disabled_pb_data); ... */
676 static void
677 status_capture_comment_hide(void)
679 edit_capture_comment_dlg_hide();
681 /* reset capture coment info indicator */
682 gtk_widget_hide(capture_comment);
683 gtk_widget_hide(capture_comment_none);
686 void
687 status_capture_comment_update(void)
689 const gchar *comment_str;
691 status_capture_comment_hide();
693 comment_str = cf_read_shb_comment(&cfile);
695 /* *comment_str==0x0 -> comment exists, but it's empty */
696 if(comment_str!=NULL && *comment_str!=0x0){
697 gtk_widget_show(capture_comment);
698 }else{
699 gtk_widget_show(capture_comment_none);
704 static void
705 statusbar_set_filename(const char *file_name, gint64 file_length, nstime_t *file_elapsed_time)
707 gchar *size_str;
709 /* expert info indicator */
710 status_expert_update();
712 /* statusbar */
713 size_str = format_size(file_length, (format_size_flags_e)(format_size_unit_bytes|format_size_prefix_si));
715 statusbar_push_file_msg(" File: \"%s\" %s %02lu:%02lu:%02lu",
716 (file_name) ? file_name : "", size_str,
717 (long)file_elapsed_time->secs/3600,
718 (long)file_elapsed_time->secs%3600/60,
719 (long)file_elapsed_time->secs%60);
720 g_free(size_str);
724 static void
725 statusbar_cf_file_closing_cb(capture_file *cf _U_)
727 /* Clear any file-related status bar messages.
728 XXX - should be "clear *ALL* file-related status bar messages;
729 will there ever be more than one on the stack? */
730 statusbar_pop_file_msg();
732 /* reset expert info indicator */
733 status_expert_hide();
734 gtk_widget_show(expert_info_none);
738 static void
739 statusbar_cf_file_closed_cb(capture_file *cf _U_)
741 /* go back to "No packets" */
742 packets_bar_update();
743 /* Remove comments icon */
744 status_capture_comment_hide();
745 /* Remove experts icon */
746 status_expert_hide();
750 static void
751 statusbar_cf_file_read_started_cb(capture_file *cf, const char *action)
753 gchar *name_ptr;
755 /* Ensure we pop any previous loaded filename */
756 statusbar_pop_file_msg();
758 name_ptr = g_filename_display_basename(cf->filename);
759 statusbar_push_file_msg(" %s: %s", action, name_ptr);
760 g_free(name_ptr);
764 static void
765 statusbar_cf_file_read_finished_cb(capture_file *cf)
767 statusbar_pop_file_msg();
768 statusbar_set_filename(cf->filename, cf->f_datalen, &(cf->elapsed_time));
769 status_capture_comment_update();
773 #ifdef HAVE_LIBPCAP
774 static void
775 statusbar_capture_prepared_cb(capture_session *cap_session _U_)
777 static const gchar msg[] = " Waiting for capture input data ...";
778 statusbar_push_file_msg(msg);
779 welcome_header_push_msg(msg);
782 static GString *
783 statusbar_get_interface_names(capture_options *capture_opts)
785 guint i;
786 GString *interface_names;
788 interface_names = g_string_new("");
790 #ifdef _WIN32
791 if (capture_opts->ifaces->len < 2) {
792 #else
793 if (capture_opts->ifaces->len < 4) {
794 #endif
795 for (i = 0; i < capture_opts->ifaces->len; i++) {
796 if (i > 0) {
797 g_string_append_printf(interface_names, ", ");
799 g_string_append_printf(interface_names, "%s", get_iface_description_for_interface(capture_opts, i));
801 } else {
802 g_string_append_printf(interface_names, "%u interfaces", capture_opts->ifaces->len);
804 if (strlen (interface_names->str) > 0) {
805 g_string_append(interface_names, ":");
807 g_string_append(interface_names, " ");
808 return (interface_names);
811 static void
812 statusbar_capture_update_started_cb(capture_session *cap_session)
814 capture_options *capture_opts = cap_session->capture_opts;
815 GString *interface_names;
817 statusbar_pop_file_msg();
818 welcome_header_pop_msg();
820 interface_names = statusbar_get_interface_names(capture_opts);
821 statusbar_push_file_msg("%s<live capture in progress> to file: %s",
822 interface_names->str,
823 (capture_opts->save_file) ? capture_opts->save_file : "");
824 g_string_free(interface_names, TRUE);
826 status_capture_comment_update();
829 static void
830 statusbar_capture_update_continue_cb(capture_session *cap_session)
832 GString *interface_names;
833 capture_options *capture_opts = cap_session->capture_opts;
834 capture_file *cf = (capture_file *)cap_session->cf;
836 status_expert_update();
838 statusbar_pop_file_msg();
840 interface_names = statusbar_get_interface_names(capture_opts);
841 if (cf->f_datalen/1024/1024 > 10) {
842 statusbar_push_file_msg("%s<live capture in progress> File: %s %" G_GINT64_MODIFIER "d MB",
843 interface_names->str,
844 capture_opts->save_file,
845 cf->f_datalen/1024/1024);
846 } else if (cf->f_datalen/1024 > 10) {
847 statusbar_push_file_msg("%s<live capture in progress> File: %s %" G_GINT64_MODIFIER "d KB",
848 interface_names->str,
849 capture_opts->save_file,
850 cf->f_datalen/1024);
851 } else {
852 statusbar_push_file_msg("%s<live capture in progress> File: %s %" G_GINT64_MODIFIER "d Bytes",
853 interface_names->str,
854 capture_opts->save_file,
855 cf->f_datalen);
857 g_string_free(interface_names, TRUE);
860 static void
861 statusbar_capture_update_finished_cb(capture_session *cap_session)
863 capture_file *cf = (capture_file *)cap_session->cf;
865 /* Pop the "<live capture in progress>" message off the status bar. */
866 statusbar_pop_file_msg();
867 statusbar_set_filename(cf->filename, cf->f_datalen, &(cf->elapsed_time));
868 packets_bar_update();
871 static void
872 statusbar_capture_fixed_started_cb(capture_session *cap_session)
874 capture_options *capture_opts = cap_session->capture_opts;
875 GString *interface_names;
877 statusbar_pop_file_msg();
879 interface_names = statusbar_get_interface_names(capture_opts);
880 statusbar_push_file_msg("%s<live capture in progress> to file: %s",
881 interface_names->str,
882 (capture_opts->save_file) ? capture_opts->save_file : "");
884 gtk_statusbar_push(GTK_STATUSBAR(packets_bar), packets_ctx, " Packets: 0");
885 g_string_free(interface_names, TRUE);
888 static void
889 statusbar_capture_fixed_continue_cb(capture_session *cap_session)
891 capture_file *cf = (capture_file *)cap_session->cf;
892 gchar *capture_msg;
895 gtk_statusbar_pop(GTK_STATUSBAR(packets_bar), packets_ctx);
896 capture_msg = g_strdup_printf(" Packets: %u", cf_get_packet_count(cf));
897 gtk_statusbar_push(GTK_STATUSBAR(packets_bar), packets_ctx, capture_msg);
898 g_free(capture_msg);
902 static void
903 statusbar_capture_fixed_finished_cb(capture_session *cap_session _U_)
905 #if 0
906 capture_file *cf = (capture_file *)cap_session->cf;
907 #endif
909 /* Pop the "<live capture in progress>" message off the status bar. */
910 statusbar_pop_file_msg();
911 welcome_header_pop_msg();
913 /* Pop the "<capturing>" message off the status bar */
914 gtk_statusbar_pop(GTK_STATUSBAR(packets_bar), packets_ctx);
917 static void
918 statusbar_capture_failed_cb(capture_session *cap_session _U_)
920 #if 0
921 capture_file *cf = (capture_file *)cap_session->cf;
922 #endif
924 /* Pop the "<live capture in progress>" message off the status bar. */
925 statusbar_pop_file_msg();
926 welcome_header_pop_msg();
928 /* Pop the "<capturing>" message off the status bar */
929 gtk_statusbar_pop(GTK_STATUSBAR(packets_bar), packets_ctx);
931 #endif /* HAVE_LIBPCAP */
934 static void
935 statusbar_cf_field_unselected_cb(capture_file *cf _U_)
937 statusbar_pop_field_msg();
940 static void
941 statusbar_cf_file_save_started_cb(gchar *filename)
943 statusbar_pop_file_msg();
944 statusbar_push_file_msg(" Saving: %s...", g_filename_display_basename(filename));
947 static void
948 statusbar_cf_file_save_finished_cb(gpointer data _U_)
950 /* Pop the "Saving:" message off the status bar. */
951 statusbar_pop_file_msg();
954 static void
955 statusbar_cf_file_save_failed_cb(gpointer data _U_)
957 /* Pop the "Saving:" message off the status bar. */
958 statusbar_pop_file_msg();
961 static void
962 statusbar_cf_file_save_stopped_cb(gpointer data _U_)
964 /* Pop the "Saving:" message off the status bar. */
965 statusbar_pop_file_msg();
968 static void
969 statusbar_cf_file_export_specified_packets_started_cb(gchar *filename)
971 statusbar_pop_file_msg();
972 statusbar_push_file_msg(" Exporting to: %s...", g_filename_display_basename(filename));
975 static void
976 statusbar_cf_file_export_specified_packets_finished_cb(gpointer data _U_)
978 /* Pop the "Exporting to:" message off the status bar. */
979 statusbar_pop_file_msg();
982 static void
983 statusbar_cf_file_export_specified_packets_failed_cb(gpointer data _U_)
985 /* Pop the "Exporting to:" message off the status bar. */
986 statusbar_pop_file_msg();
989 static void
990 statusbar_cf_file_export_specified_packets_stopped_cb(gpointer data _U_)
992 /* Pop the "Saving:" message off the status bar. */
993 statusbar_pop_file_msg();
998 void
999 statusbar_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1001 switch(event) {
1002 case(cf_cb_file_opened):
1003 break;
1004 case(cf_cb_file_closing):
1005 statusbar_cf_file_closing_cb((capture_file *)data);
1006 break;
1007 case(cf_cb_file_closed):
1008 statusbar_cf_file_closed_cb((capture_file *)data);
1009 break;
1010 case(cf_cb_file_read_started):
1011 statusbar_cf_file_read_started_cb((capture_file *)data, "Loading");
1012 break;
1013 case(cf_cb_file_read_finished):
1014 statusbar_cf_file_read_finished_cb((capture_file *)data);
1015 break;
1016 case(cf_cb_file_reload_started):
1017 statusbar_cf_file_read_started_cb((capture_file *)data, "Reloading");
1018 break;
1019 case(cf_cb_file_reload_finished):
1020 statusbar_cf_file_read_finished_cb((capture_file *)data);
1021 break;
1022 case(cf_cb_file_rescan_started):
1023 statusbar_cf_file_read_started_cb((capture_file *)data, "Rescanning");
1024 break;
1025 case(cf_cb_file_rescan_finished):
1026 statusbar_cf_file_read_finished_cb((capture_file *)data);
1027 break;
1028 case(cf_cb_file_fast_save_finished):
1029 break;
1030 case(cf_cb_packet_selected):
1031 break;
1032 case(cf_cb_packet_unselected):
1033 break;
1034 case(cf_cb_field_unselected):
1035 statusbar_cf_field_unselected_cb((capture_file *)data);
1036 break;
1037 case(cf_cb_file_save_started):
1038 statusbar_cf_file_save_started_cb((gchar *)data);
1039 break;
1040 case(cf_cb_file_save_finished):
1041 statusbar_cf_file_save_finished_cb(data);
1042 break;
1043 case(cf_cb_file_save_failed):
1044 statusbar_cf_file_save_failed_cb(data);
1045 break;
1046 case(cf_cb_file_save_stopped):
1047 statusbar_cf_file_save_stopped_cb(data);
1048 break;
1049 case(cf_cb_file_export_specified_packets_started):
1050 statusbar_cf_file_export_specified_packets_started_cb((gchar *)data);
1051 break;
1052 case(cf_cb_file_export_specified_packets_finished):
1053 statusbar_cf_file_export_specified_packets_finished_cb(data);
1054 break;
1055 case(cf_cb_file_export_specified_packets_failed):
1056 statusbar_cf_file_export_specified_packets_failed_cb(data);
1057 break;
1058 case(cf_cb_file_export_specified_packets_stopped):
1059 statusbar_cf_file_export_specified_packets_stopped_cb(data);
1060 break;
1061 default:
1062 g_warning("statusbar_cf_callback: event %u unknown", event);
1063 g_assert_not_reached();
1067 #ifdef HAVE_LIBPCAP
1068 void
1069 statusbar_capture_callback(gint event, capture_session *cap_session,
1070 gpointer user_data _U_)
1072 switch(event) {
1073 case(capture_cb_capture_prepared):
1074 statusbar_capture_prepared_cb(cap_session);
1075 break;
1076 case(capture_cb_capture_update_started):
1077 statusbar_capture_update_started_cb(cap_session);
1078 break;
1079 case(capture_cb_capture_update_continue):
1080 statusbar_capture_update_continue_cb(cap_session);
1081 break;
1082 case(capture_cb_capture_update_finished):
1083 statusbar_capture_update_finished_cb(cap_session);
1084 break;
1085 case(capture_cb_capture_fixed_started):
1086 statusbar_capture_fixed_started_cb(cap_session);
1087 break;
1088 case(capture_cb_capture_fixed_continue):
1089 statusbar_capture_fixed_continue_cb(cap_session);
1090 break;
1091 case(capture_cb_capture_fixed_finished):
1092 statusbar_capture_fixed_finished_cb(cap_session);
1093 break;
1094 case(capture_cb_capture_stopping):
1095 /* Beware: this state won't be called, if the capture child
1096 * closes the capturing on its own! */
1097 break;
1098 case(capture_cb_capture_failed):
1099 statusbar_capture_failed_cb(cap_session);
1100 break;
1101 default:
1102 g_warning("statusbar_capture_callback: event %u unknown", event);
1103 g_assert_not_reached();
1106 #endif