every GUI action, which will erease a currently unsaved capture file,
[obnox/wireshark/wip.git] / gtk / tap_dfilter_dlg.c
1 /* tap_dfilter_dlg.c
2  * Routines for display filter dialog used by gui taps
3  * Copyright 2003 Lars Roland
4  *
5  * $Id: tap_dfilter_dlg.c,v 1.5 2004/01/21 21:19:34 ulfl Exp $
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@ethereal.com>
9  * Copyright 1998 Gerald Combs
10  *
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.
15  *
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.
20  *
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.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <stdio.h>
31
32 #ifdef HAVE_SYS_TYPES_H
33 # include <sys/types.h>
34 #endif
35
36 #include <gtk/gtk.h>
37 #include <string.h>
38
39 #include "compat_macros.h"
40 #include "../simple_dialog.h"
41 #include "dlg_utils.h"
42 #include "../file.h"
43 #include "../globals.h"
44 #include "filter_prefs.h"
45 #include "../tap_dfilter_dlg.h"
46 #include "tap_dfilter_dlg.h"
47
48 extern GtkWidget *main_display_filter_widget;
49
50 typedef struct _tap_dfilter_dlg_list_item {
51         GtkWidget *dlg;
52         GtkWidget *filter_entry;
53         tap_dfilter_dlg cont;
54         construct_args_t args;
55         struct _tap_dfilter_dlg_list_item *next;
56 } tap_dfilter_dlg_list_item;
57
58 static tap_dfilter_dlg_list_item *start_dlg_list=NULL;
59 static tap_dfilter_dlg_list_item *end_dlg_list=NULL;
60 static tap_dfilter_dlg_list_item *current_dlg = NULL;
61
62 void tap_dfilter_dlg_update (void)
63 {
64         tap_dfilter_dlg_list_item *dialog = start_dlg_list;
65         char *title;
66         
67         while(dialog != NULL) {
68                 if(dialog->dlg) {
69                         title = g_strdup_printf("Ethereal: %s: %s", dialog->cont.win_title , cf_get_display_name(&cfile));
70                         gtk_window_set_title(GTK_WINDOW(dialog->dlg), title);
71                         g_free(title);
72                 }
73                 dialog = dialog->next;          
74         }
75 }
76
77 static void
78 dlg_destroy_cb(GtkWidget *item _U_, gpointer dialog_data)
79 {       
80         tap_dfilter_dlg_list_item *dlg_data = (tap_dfilter_dlg_list_item *) dialog_data;
81         dlg_data->dlg = NULL;
82 }
83
84 static void
85 dlg_cancel_cb(GtkWidget *cancel_bt _U_, gpointer parent_w)
86 {
87         gtk_widget_destroy(GTK_WIDGET(parent_w));
88 }
89
90 static void
91 tap_dfilter_dlg_start_button_clicked(GtkWidget *item _U_, gpointer dialog_data)
92 {
93         char *filter;
94         char str[256];
95         
96         tap_dfilter_dlg_list_item *dlg_data = (tap_dfilter_dlg_list_item *) dialog_data;
97
98         filter=(char *)gtk_entry_get_text(GTK_ENTRY(dlg_data->filter_entry));
99         if(filter[0]==0){
100                 sprintf(str,"%s", dlg_data->cont.init_string);
101         } else {
102                 sprintf(str,"%s,%s", dlg_data->cont.init_string, filter);               
103         }
104         (dlg_data->cont.tap_init_cb)(str);
105 }
106
107
108 void
109 gtk_tap_dfilter_dlg_cb(GtkWidget *w _U_, gpointer data)
110 {
111         const char *filter;
112         char *title;
113         GtkWidget *dlg_box;
114         GtkWidget *filter_box, *filter_bt;
115         GtkWidget *bbox, *start_button, *cancel_button;
116         
117         tap_dfilter_dlg *dlg_data = (tap_dfilter_dlg *) data;   
118
119         if(dlg_data==NULL)
120                 return;
121                 
122         if(dlg_data->index==-1) {
123                 /* Dialog is not registered */
124                 if(start_dlg_list==NULL) {
125                         start_dlg_list = (tap_dfilter_dlg_list_item *) g_malloc(sizeof (tap_dfilter_dlg_list_item));
126                         end_dlg_list = start_dlg_list;
127                         end_dlg_list->cont.index = 0; /* first entry in list -> index = 0 */
128                 } else {
129                         end_dlg_list->next = (tap_dfilter_dlg_list_item *) g_malloc(sizeof (tap_dfilter_dlg_list_item));
130                         end_dlg_list->next->cont.index = end_dlg_list->cont.index + 1;
131                         end_dlg_list = end_dlg_list->next;
132                 }
133                 end_dlg_list->dlg = NULL;
134                 end_dlg_list->filter_entry = NULL;
135                 end_dlg_list->cont.win_title = dlg_data->win_title;
136                 end_dlg_list->cont.init_string = dlg_data->init_string;
137                 end_dlg_list->cont.tap_init_cb = dlg_data->tap_init_cb;
138                 end_dlg_list->args.title = g_strdup_printf("%s Filter", dlg_data->win_title);
139                 end_dlg_list->args.wants_apply_button = TRUE;
140                 end_dlg_list->args.activate_on_ok = FALSE;
141                 end_dlg_list->next = NULL;
142                 dlg_data->index = end_dlg_list->cont.index;
143                 current_dlg = end_dlg_list;
144         } else {
145                 /* Dialog is registered, find it */
146                 current_dlg = start_dlg_list;
147                 while(dlg_data->index != current_dlg->cont.index)
148                 {
149                         if(current_dlg->next == NULL) {
150                                 /* could not find any dialog */
151                                 return;
152                         }
153                         current_dlg = current_dlg->next;
154                 }
155         }
156
157         /* if the window is already open, bring it to front */
158         if(current_dlg->dlg){
159                 gdk_window_raise(current_dlg->dlg->window);
160                 return;
161         }
162
163         title = g_strdup_printf("Ethereal: %s: %s", current_dlg->cont.win_title , cf_get_display_name(&cfile));
164
165         current_dlg->dlg=dlg_window_new(title);
166         g_free(title);
167         SIGNAL_CONNECT(current_dlg->dlg, "destroy", dlg_destroy_cb, current_dlg);
168
169         dlg_box=gtk_vbox_new(FALSE, 10);
170         gtk_container_border_width(GTK_CONTAINER(dlg_box), 10);
171         gtk_container_add(GTK_CONTAINER(current_dlg->dlg), dlg_box);
172         gtk_widget_show(dlg_box);
173
174         /* Filter box */
175         filter_box=gtk_hbox_new(FALSE, 3);
176
177         /* Filter button */
178         filter_bt=BUTTON_NEW_FROM_STOCK(ETHEREAL_STOCK_DISPLAY_FILTER_ENTRY);
179         SIGNAL_CONNECT(filter_bt, "clicked", display_filter_construct_cb, &(current_dlg->args));
180         gtk_box_pack_start(GTK_BOX(filter_box), filter_bt, FALSE, TRUE, 0);
181         gtk_widget_show(filter_bt);
182
183         /* Filter entry */
184         current_dlg->filter_entry=gtk_entry_new();
185         WIDGET_SET_SIZE(current_dlg->filter_entry, 300, 25);
186         
187         /* filter prefs dialog */
188         OBJECT_SET_DATA(filter_bt, E_FILT_TE_PTR_KEY, current_dlg->filter_entry);
189         /* filter prefs dialog */
190         
191         gtk_box_pack_start(GTK_BOX(filter_box), current_dlg->filter_entry, TRUE, TRUE, 0);
192         filter=gtk_entry_get_text(GTK_ENTRY(main_display_filter_widget));
193         if(filter){
194                 gtk_entry_set_text(GTK_ENTRY(current_dlg->filter_entry), filter);
195         }
196         gtk_widget_show(current_dlg->filter_entry);
197
198         gtk_box_pack_start(GTK_BOX(dlg_box), filter_box, TRUE, TRUE, 0);
199         gtk_widget_show(filter_box);
200
201         /* button box */
202     bbox = dlg_button_row_new(ETHEREAL_STOCK_CREATE_STAT, GTK_STOCK_CANCEL, NULL);
203         gtk_box_pack_start(GTK_BOX(dlg_box), bbox, FALSE, FALSE, 0);
204     gtk_widget_show(bbox);
205
206     start_button = OBJECT_GET_DATA(bbox, ETHEREAL_STOCK_CREATE_STAT);
207     gtk_widget_grab_default(start_button );
208     SIGNAL_CONNECT(start_button, "clicked",
209                               tap_dfilter_dlg_start_button_clicked, current_dlg);
210
211     cancel_button = OBJECT_GET_DATA(bbox, GTK_STOCK_CANCEL);
212         SIGNAL_CONNECT(cancel_button, "clicked", dlg_cancel_cb, current_dlg->dlg);
213
214         /* Catch the "activate" signal on the filter text entry, so that
215            if the user types Return there, we act as if the "Create Stat"
216            button had been selected, as happens if Return is typed if
217            some widget that *doesn't* handle the Return key has the input
218            focus. */
219         dlg_set_activate(current_dlg->filter_entry, start_button);
220
221         /* Catch the "key_press_event" signal in the window, so that we can
222            catch the ESC key being pressed and act as if the "Cancel" button
223            had been selected. */
224         dlg_set_cancel(current_dlg->dlg, cancel_button);
225
226         /* Give the initial focus to the "Filter" entry box. */
227         gtk_widget_grab_focus(current_dlg->filter_entry);
228
229         gtk_widget_show_all(current_dlg->dlg);
230 }