2 * Routines for display filter dialog used by gui taps
3 * Copyright 2003 Lars Roland
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
33 #ifdef HAVE_SYS_TYPES_H
34 # include <sys/types.h>
39 #include <epan/stat_cmd_args.h>
41 #include "../simple_dialog.h"
43 #include "../globals.h"
44 #include "../stat_menu.h"
46 #include "gtk/stock_icons.h"
47 #include "gtk/dlg_utils.h"
48 #include "gtk/filter_dlg.h"
49 #include "gtk/gui_stat_menu.h"
50 #include "gtk/tap_dfilter_dlg.h"
51 #include "gtk/gui_utils.h"
52 #include "gtk/gtkglobals.h"
53 #include "gtk/filter_autocomplete.h"
56 typedef struct _tap_dfilter_dlg_list_item {
58 GtkWidget *filter_entry;
60 construct_args_t args;
61 struct _tap_dfilter_dlg_list_item *next;
62 } tap_dfilter_dlg_list_item;
64 static tap_dfilter_dlg_list_item *start_dlg_list=NULL;
65 static tap_dfilter_dlg_list_item *end_dlg_list=NULL;
66 static tap_dfilter_dlg_list_item *current_dlg = NULL;
69 tap_dfilter_dlg_cb(GtkWidget *w, gpointer data);
72 * Register a stat that has a display filter dialog.
73 * We register it both as a command-line stat and a menu item stat.
76 register_dfilter_stat(tap_dfilter_dlg *info, const char *name,
77 register_stat_group_t group)
81 register_stat_cmd_arg(info->init_string, info->tap_init_cb, NULL);
84 * This menu item will pop up a dialog box, so append "..."
87 full_name = g_strdup_printf("%s...", name);
88 register_stat_menu_item(full_name, group, tap_dfilter_dlg_cb, NULL,
93 void tap_dfilter_dlg_update (void)
95 tap_dfilter_dlg_list_item *dialog = start_dlg_list;
98 while(dialog != NULL) {
100 title = g_strdup_printf("Wireshark: %s: %s", dialog->cont.win_title , cf_get_display_name(&cfile));
101 gtk_window_set_title(GTK_WINDOW(dialog->dlg), title);
104 dialog = dialog->next;
109 dlg_destroy_cb(GtkWidget *item _U_, gpointer dialog_data)
111 tap_dfilter_dlg_list_item *dlg_data = (tap_dfilter_dlg_list_item *) dialog_data;
112 dlg_data->dlg = NULL;
116 tap_dfilter_dlg_start_button_clicked(GtkWidget *item _U_, gpointer dialog_data)
121 tap_dfilter_dlg_list_item *dlg_data = (tap_dfilter_dlg_list_item *) dialog_data;
123 filter=gtk_entry_get_text(GTK_ENTRY(dlg_data->filter_entry));
125 str = g_strdup_printf("%s", dlg_data->cont.init_string);
127 str = g_strdup_printf("%s,%s", dlg_data->cont.init_string,
130 (dlg_data->cont.tap_init_cb)(str,NULL);
137 tap_dfilter_dlg_cb(GtkWidget *w _U_, gpointer data)
142 GtkWidget *filter_box, *filter_bt;
143 GtkWidget *bbox, *start_button, *cancel_button;
145 tap_dfilter_dlg *dlg_data = (tap_dfilter_dlg *) data;
150 if(dlg_data->index==-1) {
151 /* Dialog is not registered */
152 if(start_dlg_list==NULL) {
153 start_dlg_list = (tap_dfilter_dlg_list_item *) g_malloc(sizeof (tap_dfilter_dlg_list_item));
154 end_dlg_list = start_dlg_list;
155 end_dlg_list->cont.index = 0; /* first entry in list -> index = 0 */
157 end_dlg_list->next = (tap_dfilter_dlg_list_item *) g_malloc(sizeof (tap_dfilter_dlg_list_item));
158 end_dlg_list->next->cont.index = end_dlg_list->cont.index + 1;
159 end_dlg_list = end_dlg_list->next;
161 end_dlg_list->dlg = NULL;
162 end_dlg_list->filter_entry = NULL;
163 end_dlg_list->cont.win_title = dlg_data->win_title;
164 end_dlg_list->cont.init_string = dlg_data->init_string;
165 end_dlg_list->cont.tap_init_cb = dlg_data->tap_init_cb;
166 end_dlg_list->args.title = g_strdup_printf("%s Filter", dlg_data->win_title);
167 end_dlg_list->args.wants_apply_button = TRUE;
168 end_dlg_list->args.activate_on_ok = FALSE;
169 end_dlg_list->args.modal_and_transient = FALSE;
170 end_dlg_list->next = NULL;
171 dlg_data->index = end_dlg_list->cont.index;
172 current_dlg = end_dlg_list;
174 /* Dialog is registered, find it */
175 current_dlg = start_dlg_list;
176 while(dlg_data->index != current_dlg->cont.index)
178 if(current_dlg->next == NULL) {
179 /* could not find any dialog */
182 current_dlg = current_dlg->next;
186 /* if the window is already open, bring it to front */
187 if(current_dlg->dlg){
188 gdk_window_raise(current_dlg->dlg->window);
192 title = g_strdup_printf("Wireshark: %s: %s", current_dlg->cont.win_title , cf_get_display_name(&cfile));
194 current_dlg->dlg=dlg_window_new(title);
195 gtk_window_set_default_size(GTK_WINDOW(current_dlg->dlg), 300, -1);
198 dlg_box=gtk_vbox_new(FALSE, 10);
199 gtk_container_set_border_width(GTK_CONTAINER(dlg_box), 10);
200 gtk_container_add(GTK_CONTAINER(current_dlg->dlg), dlg_box);
201 gtk_widget_show(dlg_box);
204 filter_box=gtk_hbox_new(FALSE, 3);
207 filter_bt=gtk_button_new_from_stock(WIRESHARK_STOCK_DISPLAY_FILTER_ENTRY);
208 g_signal_connect(filter_bt, "clicked", G_CALLBACK(display_filter_construct_cb), &(current_dlg->args));
209 gtk_box_pack_start(GTK_BOX(filter_box), filter_bt, FALSE, TRUE, 0);
210 gtk_widget_show(filter_bt);
213 current_dlg->filter_entry=gtk_entry_new();
214 g_signal_connect(current_dlg->filter_entry, "changed", G_CALLBACK(filter_te_syntax_check_cb), NULL);
215 g_object_set_data(G_OBJECT(filter_box), E_FILT_AUTOCOMP_PTR_KEY, NULL);
216 g_signal_connect(current_dlg->filter_entry, "key-press-event", G_CALLBACK (filter_string_te_key_pressed_cb), NULL);
217 g_signal_connect(current_dlg->dlg, "key-press-event", G_CALLBACK (filter_parent_dlg_key_pressed_cb), NULL);
219 /* filter prefs dialog */
220 g_object_set_data(G_OBJECT(filter_bt), E_FILT_TE_PTR_KEY, current_dlg->filter_entry);
221 /* filter prefs dialog */
223 gtk_box_pack_start(GTK_BOX(filter_box), current_dlg->filter_entry, TRUE, TRUE, 0);
224 filter=gtk_entry_get_text(GTK_ENTRY(main_display_filter_widget));
226 gtk_entry_set_text(GTK_ENTRY(current_dlg->filter_entry), filter);
228 colorize_filter_te_as_empty(current_dlg->filter_entry);
230 gtk_widget_show(current_dlg->filter_entry);
232 gtk_box_pack_start(GTK_BOX(dlg_box), filter_box, TRUE, TRUE, 0);
233 gtk_widget_show(filter_box);
236 bbox = dlg_button_row_new(WIRESHARK_STOCK_CREATE_STAT, GTK_STOCK_CANCEL, NULL);
237 gtk_box_pack_start(GTK_BOX(dlg_box), bbox, FALSE, FALSE, 0);
238 gtk_widget_show(bbox);
240 start_button = g_object_get_data(G_OBJECT(bbox), WIRESHARK_STOCK_CREATE_STAT);
241 g_signal_connect(start_button, "clicked",
242 G_CALLBACK(tap_dfilter_dlg_start_button_clicked), current_dlg);
244 cancel_button = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CANCEL);
245 window_set_cancel_button(current_dlg->dlg, cancel_button, window_cancel_button_cb);
247 /* Catch the "activate" signal on the filter text entry, so that
248 if the user types Return there, we act as if the "Create Stat"
249 button had been selected, as happens if Return is typed if
250 some widget that *doesn't* handle the Return key has the input
252 dlg_set_activate(current_dlg->filter_entry, start_button);
254 /* Give the initial focus to the "Filter" entry box. */
255 gtk_widget_grab_focus(current_dlg->filter_entry);
257 gtk_widget_grab_default(start_button );
259 g_signal_connect(current_dlg->dlg, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
260 g_signal_connect(current_dlg->dlg, "destroy", G_CALLBACK(dlg_destroy_cb), current_dlg);
262 gtk_widget_show_all(current_dlg->dlg);
263 window_present(current_dlg->dlg);