2 * Routines for parameter 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
33 #include <epan/stat_cmd_args.h>
36 #include "../globals.h"
37 #include "../stat_menu.h"
39 #include "ui/gtk/stock_icons.h"
40 #include "ui/gtk/dlg_utils.h"
41 #include "ui/gtk/filter_dlg.h"
42 #include "ui/gtk/gui_stat_menu.h"
43 #include "ui/gtk/tap_param_dlg.h"
44 #include "ui/gtk/gui_utils.h"
45 #include "ui/gtk/gtkglobals.h"
46 #include "ui/gtk/filter_autocomplete.h"
48 #include "ui/gtk/old-gtk-compat.h"
50 typedef struct _tap_param_dlg_list_item {
53 construct_args_t args;
54 GtkWidget **param_items; /* items for params */
55 struct _tap_param_dlg_list_item *next;
56 } tap_param_dlg_list_item;
58 static tap_param_dlg_list_item *start_dlg_list=NULL;
59 static tap_param_dlg_list_item *end_dlg_list=NULL;
60 static tap_param_dlg_list_item *current_dlg = NULL;
63 * Register a stat that has a parameter dialog.
64 * We register it both as a command-line stat and a menu item stat.
67 register_param_stat(tap_param_dlg *info, const char *name,
68 register_stat_group_t group)
71 const gchar *stock_id = NULL;
73 register_stat_cmd_arg(info->init_string, info->tap_init_cb, NULL);
76 * This menu item will pop up a dialog box, so append "..."
79 full_name = g_strdup_printf("%s...", name);
83 case REGISTER_ANALYZE_GROUP_UNSORTED:
84 case REGISTER_ANALYZE_GROUP_CONVERSATION_FILTER:
85 case REGISTER_STAT_GROUP_UNSORTED:
86 case REGISTER_STAT_GROUP_GENERIC:
89 case REGISTER_STAT_GROUP_CONVERSATION_LIST:
90 stock_id = WIRESHARK_STOCK_CONVERSATIONS;
93 case REGISTER_STAT_GROUP_ENDPOINT_LIST:
94 stock_id = WIRESHARK_STOCK_ENDPOINTS;
97 case REGISTER_STAT_GROUP_RESPONSE_TIME:
98 stock_id = WIRESHARK_STOCK_TIME;
101 case REGISTER_STAT_GROUP_TELEPHONY:
102 case REGISTER_STAT_GROUP_TELEPHONY_GSM:
103 case REGISTER_STAT_GROUP_TELEPHONY_LTE:
106 case REGISTER_TOOLS_GROUP_UNSORTED:
110 register_menu_bar_menu_items(
111 stat_group_name(group), /* GUI path to the place holder in the menu */
112 name, /* Action name */
113 stock_id, /* Stock id */
114 full_name, /* label */
115 NULL, /* Accelerator */
117 tap_param_dlg_cb, /* Callback */
118 info, /* Callback data */
124 void tap_param_dlg_update (void)
126 tap_param_dlg_list_item *dialog = start_dlg_list;
130 while(dialog != NULL) {
132 display_name = cf_get_display_name(&cfile);
133 title = g_strdup_printf("Wireshark: %s: %s", dialog->cont.win_title , display_name);
134 g_free(display_name);
135 gtk_window_set_title(GTK_WINDOW(dialog->dlg), title);
138 dialog = dialog->next;
143 dlg_destroy_cb(GtkWidget *item _U_, gpointer dialog_data)
145 tap_param_dlg_list_item *dlg_data = (tap_param_dlg_list_item *) dialog_data;
146 dlg_data->dlg = NULL;
150 tap_param_dlg_start_button_clicked(GtkWidget *item _U_, gpointer dialog_data)
156 tap_param_dlg_list_item *dlg_data = (tap_param_dlg_list_item *) dialog_data;
158 params = g_string_new(dlg_data->cont.init_string);
159 for(i=0;i<dlg_data->cont.nparams;i++) {
160 g_string_append_c(params, ',');
161 switch (dlg_data->cont.params[i].type) {
164 j = gtk_combo_box_get_active(GTK_COMBO_BOX(dlg_data->param_items[i]));
165 g_string_append_printf(params,"%d",
166 dlg_data->cont.params[i].enum_vals[j].value);
172 g_string_append(params,
173 gtk_entry_get_text(GTK_ENTRY(dlg_data->param_items[i])));
177 (dlg_data->cont.tap_init_cb)(params->str,NULL);
178 g_string_free(params, TRUE);
182 tap_param_dlg_cb(GtkAction *action _U_, gpointer data)
188 GtkWidget *item_box, *item, *label, *filter_bt;
189 GtkWidget *bbox, *start_button, *cancel_button;
191 char *label_with_colon;
193 tap_param_dlg *dlg_data = (tap_param_dlg *) data;
198 if(dlg_data->index==-1) {
199 /* Dialog is not registered */
200 if(start_dlg_list==NULL) {
201 start_dlg_list = (tap_param_dlg_list_item *) g_malloc(sizeof (tap_param_dlg_list_item));
202 end_dlg_list = start_dlg_list;
203 end_dlg_list->cont.index = 0; /* first entry in list -> index = 0 */
205 end_dlg_list->next = (tap_param_dlg_list_item *) g_malloc(sizeof (tap_param_dlg_list_item));
206 end_dlg_list->next->cont.index = end_dlg_list->cont.index + 1;
207 end_dlg_list = end_dlg_list->next;
209 end_dlg_list->dlg = NULL;
210 end_dlg_list->param_items = (GtkWidget **)g_malloc(dlg_data->nparams * sizeof (GtkWidget *));
211 end_dlg_list->cont.win_title = dlg_data->win_title;
212 end_dlg_list->cont.init_string = dlg_data->init_string;
213 end_dlg_list->cont.tap_init_cb = dlg_data->tap_init_cb;
214 end_dlg_list->cont.nparams = dlg_data->nparams;
215 end_dlg_list->cont.params = dlg_data->params;
216 end_dlg_list->args.title = g_strdup_printf("%s Filter", dlg_data->win_title);
217 end_dlg_list->args.wants_apply_button = TRUE;
218 end_dlg_list->args.activate_on_ok = FALSE;
219 end_dlg_list->args.modal_and_transient = FALSE;
220 end_dlg_list->next = NULL;
221 dlg_data->index = end_dlg_list->cont.index;
222 current_dlg = end_dlg_list;
224 /* Dialog is registered, find it */
225 current_dlg = start_dlg_list;
226 while(dlg_data->index != current_dlg->cont.index)
228 if(current_dlg->next == NULL) {
229 /* could not find any dialog */
232 current_dlg = current_dlg->next;
236 /* if the window is already open, bring it to front */
237 if(current_dlg->dlg){
238 gdk_window_raise(gtk_widget_get_window(current_dlg->dlg));
242 display_name = cf_get_display_name(&cfile);
243 title = g_strdup_printf("Wireshark: %s: %s", current_dlg->cont.win_title , display_name);
244 g_free(display_name);
246 current_dlg->dlg=dlg_window_new(title);
247 gtk_window_set_default_size(GTK_WINDOW(current_dlg->dlg), 300, -1);
250 dlg_box=ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 10, FALSE);
251 gtk_container_set_border_width(GTK_CONTAINER(dlg_box), 10);
252 gtk_container_add(GTK_CONTAINER(current_dlg->dlg), dlg_box);
253 gtk_widget_show(dlg_box);
255 /* Parameter items */
256 for(i=0;i<current_dlg->cont.nparams;i++) {
258 item_box=ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE);
260 switch (current_dlg->cont.params[i].type) {
265 label_with_colon=g_strdup_printf("%s:", current_dlg->cont.params[i].title);
266 label=gtk_label_new(label_with_colon);
267 g_free(label_with_colon);
268 gtk_box_pack_start(GTK_BOX(item_box), label, FALSE, TRUE, 0);
269 gtk_widget_show(label);
272 item=gtk_entry_new();
277 label_with_colon=g_strdup_printf("%s:", current_dlg->cont.params[i].title);
278 label=gtk_label_new(label_with_colon);
279 g_free(label_with_colon);
280 gtk_box_pack_start(GTK_BOX(item_box), label, FALSE, TRUE, 0);
281 gtk_widget_show(label);
284 item=gtk_combo_box_text_new();
285 for (j = 0; current_dlg->cont.params[i].enum_vals[j].name != NULL;
287 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(item),
288 current_dlg->cont.params[i].enum_vals[j].description);
289 gtk_combo_box_set_active(GTK_COMBO_BOX(item), 0);
294 filter_bt=gtk_button_new_from_stock(WIRESHARK_STOCK_DISPLAY_FILTER_ENTRY);
295 g_signal_connect(filter_bt, "clicked", G_CALLBACK(display_filter_construct_cb), &(current_dlg->args));
296 gtk_box_pack_start(GTK_BOX(item_box), filter_bt, FALSE, TRUE, 0);
297 gtk_widget_show(filter_bt);
300 item=gtk_entry_new();
301 g_signal_connect(item, "changed", G_CALLBACK(filter_te_syntax_check_cb), NULL);
302 g_object_set_data(G_OBJECT(item_box), E_FILT_AUTOCOMP_PTR_KEY, NULL);
303 g_signal_connect(item, "key-press-event", G_CALLBACK (filter_string_te_key_pressed_cb), NULL);
304 g_signal_connect(current_dlg->dlg, "key-press-event", G_CALLBACK (filter_parent_dlg_key_pressed_cb), NULL);
305 g_object_set_data(G_OBJECT(filter_bt), E_FILT_TE_PTR_KEY, item);
307 filter=gtk_entry_get_text(GTK_ENTRY(main_display_filter_widget));
309 gtk_entry_set_text(GTK_ENTRY(item), filter);
311 colorize_filter_te_as_empty(item);
316 g_assert_not_reached();
321 gtk_box_pack_start(GTK_BOX(item_box), item, TRUE, TRUE, 0);
322 current_dlg->param_items[i]=item;
323 gtk_widget_show(item);
325 gtk_box_pack_start(GTK_BOX(dlg_box), item_box, TRUE, TRUE, 0);
326 gtk_widget_show(item_box);
330 bbox = dlg_button_row_new(WIRESHARK_STOCK_CREATE_STAT, GTK_STOCK_CANCEL, NULL);
331 gtk_box_pack_start(GTK_BOX(dlg_box), bbox, FALSE, FALSE, 0);
332 gtk_widget_show(bbox);
334 start_button = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), WIRESHARK_STOCK_CREATE_STAT);
335 g_signal_connect(start_button, "clicked",
336 G_CALLBACK(tap_param_dlg_start_button_clicked), current_dlg);
338 cancel_button = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CANCEL);
339 window_set_cancel_button(current_dlg->dlg, cancel_button, window_cancel_button_cb);
341 /* Catch the "activate" signal on all the text entries, so that
342 if the user types Return there, we act as if the "Create Stat"
343 button had been selected, as happens if Return is typed if
344 some widget that *doesn't* handle the Return key has the input
346 for(i=0;i<current_dlg->cont.nparams;i++){
347 switch (current_dlg->cont.params[i].type) {
355 dlg_set_activate(current_dlg->param_items[i], start_button);
360 /* Give the initial focus to the first entry box. */
361 if(current_dlg->cont.nparams>0){
362 gtk_widget_grab_focus(current_dlg->param_items[0]);
365 gtk_widget_grab_default(start_button );
367 g_signal_connect(current_dlg->dlg, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
368 g_signal_connect(current_dlg->dlg, "destroy", G_CALLBACK(dlg_destroy_cb), current_dlg);
370 gtk_widget_show_all(current_dlg->dlg);
371 window_present(current_dlg->dlg);