add parameter dcerpc_info to PIDL_dissect_ipv?address()
[wireshark-wip.git] / ui / gtk / tap_param_dlg.c
blob7d4dc2c45206f3ea1597be8f6aacc8501386a155
1 /* tap_param_dlg.c
2 * Routines for parameter dialog used by gui taps
3 * Copyright 2003 Lars Roland
5 * $Id$
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.
26 #include "config.h"
28 #include <stdio.h>
29 #include <string.h>
31 #include <gtk/gtk.h>
33 #include <epan/stat_cmd_args.h>
35 #include "../file.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 {
51 GtkWidget *dlg;
52 tap_param_dlg cont;
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.
66 void
67 register_param_stat(tap_param_dlg *info, const char *name,
68 register_stat_group_t group)
70 gchar *full_name;
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 "..."
77 * to it.
79 full_name = g_strdup_printf("%s...", name);
81 switch (group) {
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:
87 break;
89 case REGISTER_STAT_GROUP_CONVERSATION_LIST:
90 stock_id = WIRESHARK_STOCK_CONVERSATIONS;
91 break;
93 case REGISTER_STAT_GROUP_ENDPOINT_LIST:
94 stock_id = WIRESHARK_STOCK_ENDPOINTS;
95 break;
97 case REGISTER_STAT_GROUP_RESPONSE_TIME:
98 stock_id = WIRESHARK_STOCK_TIME;
99 break;
101 case REGISTER_STAT_GROUP_TELEPHONY:
102 case REGISTER_STAT_GROUP_TELEPHONY_GSM:
103 case REGISTER_STAT_GROUP_TELEPHONY_LTE:
104 case REGISTER_STAT_GROUP_TELEPHONY_SCTP:
105 break;
107 case REGISTER_TOOLS_GROUP_UNSORTED:
108 break;
111 register_menu_bar_menu_items(
112 stat_group_name(group), /* GUI path to the place holder in the menu */
113 name, /* Action name */
114 stock_id, /* Stock id */
115 full_name, /* label */
116 NULL, /* Accelerator */
117 NULL, /* Tooltip */
118 tap_param_dlg_cb, /* Callback */
119 info, /* Callback data */
120 TRUE, /* Enabled */
121 NULL,
122 NULL);
125 void tap_param_dlg_update (void)
127 tap_param_dlg_list_item *dialog = start_dlg_list;
128 char *display_name;
129 char *title;
131 while(dialog != NULL) {
132 if(dialog->dlg) {
133 display_name = cf_get_display_name(&cfile);
134 title = g_strdup_printf("Wireshark: %s: %s", dialog->cont.win_title , display_name);
135 g_free(display_name);
136 gtk_window_set_title(GTK_WINDOW(dialog->dlg), title);
137 g_free(title);
139 dialog = dialog->next;
143 static void
144 dlg_destroy_cb(GtkWidget *item _U_, gpointer dialog_data)
146 tap_param_dlg_list_item *dlg_data = (tap_param_dlg_list_item *) dialog_data;
147 dlg_data->dlg = NULL;
150 static void
151 tap_param_dlg_start_button_clicked(GtkWidget *item _U_, gpointer dialog_data)
153 GString *params;
154 size_t i;
155 gdouble d;
156 gint j;
158 tap_param_dlg_list_item *dlg_data = (tap_param_dlg_list_item *) dialog_data;
160 params = g_string_new(dlg_data->cont.init_string);
161 for(i=0;i<dlg_data->cont.nparams;i++) {
162 g_string_append_c(params, ',');
163 switch (dlg_data->cont.params[i].type) {
165 case PARAM_ENUM:
166 j = gtk_combo_box_get_active(GTK_COMBO_BOX(dlg_data->param_items[i]));
167 g_string_append_printf(params,"%d",
168 dlg_data->cont.params[i].enum_vals[j].value);
169 break;
171 case PARAM_UINT:
172 d = gtk_spin_button_get_value(GTK_SPIN_BUTTON(dlg_data->param_items[i]));
173 g_string_append_printf(params,"%u",(guint)d);
174 break;
176 case PARAM_STRING:
177 case PARAM_FILTER:
178 g_string_append(params,
179 gtk_entry_get_text(GTK_ENTRY(dlg_data->param_items[i])));
180 break;
183 (dlg_data->cont.tap_init_cb)(params->str,NULL);
184 g_string_free(params, TRUE);
187 void
188 tap_param_dlg_cb(GtkAction *action _U_, gpointer data)
190 const char *filter;
191 char *display_name;
192 char *title;
193 GtkWidget *dlg_box;
194 GtkWidget *item_box, *item, *label, *filter_bt;
195 GtkWidget *bbox, *start_button, *cancel_button;
196 size_t i, j;
197 char *label_with_colon;
199 tap_param_dlg *dlg_data = (tap_param_dlg *) data;
201 if(dlg_data==NULL)
202 return;
204 if(dlg_data->index==-1) {
205 /* Dialog is not registered */
206 if(start_dlg_list==NULL) {
207 start_dlg_list = (tap_param_dlg_list_item *) g_malloc(sizeof (tap_param_dlg_list_item));
208 end_dlg_list = start_dlg_list;
209 end_dlg_list->cont.index = 0; /* first entry in list -> index = 0 */
210 } else {
211 end_dlg_list->next = (tap_param_dlg_list_item *) g_malloc(sizeof (tap_param_dlg_list_item));
212 end_dlg_list->next->cont.index = end_dlg_list->cont.index + 1;
213 end_dlg_list = end_dlg_list->next;
215 end_dlg_list->dlg = NULL;
216 end_dlg_list->param_items = (GtkWidget **)g_malloc(dlg_data->nparams * sizeof (GtkWidget *));
217 end_dlg_list->cont.win_title = dlg_data->win_title;
218 end_dlg_list->cont.init_string = dlg_data->init_string;
219 end_dlg_list->cont.tap_init_cb = dlg_data->tap_init_cb;
220 end_dlg_list->cont.nparams = dlg_data->nparams;
221 end_dlg_list->cont.params = dlg_data->params;
222 end_dlg_list->args.title = g_strdup_printf("%s Filter", dlg_data->win_title);
223 end_dlg_list->args.wants_apply_button = TRUE;
224 end_dlg_list->args.activate_on_ok = FALSE;
225 end_dlg_list->args.modal_and_transient = FALSE;
226 end_dlg_list->next = NULL;
227 dlg_data->index = end_dlg_list->cont.index;
228 current_dlg = end_dlg_list;
229 } else {
230 /* Dialog is registered, find it */
231 current_dlg = start_dlg_list;
232 while(dlg_data->index != current_dlg->cont.index)
234 if(current_dlg->next == NULL) {
235 /* could not find any dialog */
236 return;
238 current_dlg = current_dlg->next;
242 /* if the window is already open, bring it to front */
243 if(current_dlg->dlg){
244 gdk_window_raise(gtk_widget_get_window(current_dlg->dlg));
245 return;
248 display_name = cf_get_display_name(&cfile);
249 title = g_strdup_printf("Wireshark: %s: %s", current_dlg->cont.win_title , display_name);
250 g_free(display_name);
252 current_dlg->dlg=dlg_window_new(title);
253 gtk_window_set_default_size(GTK_WINDOW(current_dlg->dlg), 300, -1);
254 g_free(title);
256 dlg_box=ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 10, FALSE);
257 gtk_container_set_border_width(GTK_CONTAINER(dlg_box), 10);
258 gtk_container_add(GTK_CONTAINER(current_dlg->dlg), dlg_box);
259 gtk_widget_show(dlg_box);
261 /* Parameter items */
262 for(i=0;i<current_dlg->cont.nparams;i++) {
263 /* Item box */
264 item_box=ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE);
266 switch (current_dlg->cont.params[i].type) {
268 case PARAM_UINT:
269 /* Label */
270 label_with_colon=g_strdup_printf("%s:", current_dlg->cont.params[i].title);
271 label=gtk_label_new(label_with_colon);
272 g_free(label_with_colon);
273 gtk_box_pack_start(GTK_BOX(item_box), label, FALSE, TRUE, 0);
274 gtk_widget_show(label);
276 /* Spin button */
277 item=gtk_spin_button_new_with_range(0, G_MAXUINT, 1);
278 gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(item), TRUE);
280 break;
282 case PARAM_STRING:
283 /* Label */
284 label_with_colon=g_strdup_printf("%s:", current_dlg->cont.params[i].title);
285 label=gtk_label_new(label_with_colon);
286 g_free(label_with_colon);
287 gtk_box_pack_start(GTK_BOX(item_box), label, FALSE, TRUE, 0);
288 gtk_widget_show(label);
290 /* Entry */
291 item=gtk_entry_new();
292 break;
294 case PARAM_ENUM:
295 /* Label */
296 label_with_colon=g_strdup_printf("%s:", current_dlg->cont.params[i].title);
297 label=gtk_label_new(label_with_colon);
298 g_free(label_with_colon);
299 gtk_box_pack_start(GTK_BOX(item_box), label, FALSE, TRUE, 0);
300 gtk_widget_show(label);
302 /* Combo box */
303 item=gtk_combo_box_text_new();
304 for (j = 0; current_dlg->cont.params[i].enum_vals[j].name != NULL;
305 j++)
306 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(item),
307 current_dlg->cont.params[i].enum_vals[j].description);
308 gtk_combo_box_set_active(GTK_COMBO_BOX(item), 0);
309 break;
311 case PARAM_FILTER:
312 /* Filter button */
313 filter_bt=gtk_button_new_from_stock(WIRESHARK_STOCK_DISPLAY_FILTER_ENTRY);
314 g_signal_connect(filter_bt, "clicked", G_CALLBACK(display_filter_construct_cb), &(current_dlg->args));
315 gtk_box_pack_start(GTK_BOX(item_box), filter_bt, FALSE, TRUE, 0);
316 gtk_widget_show(filter_bt);
318 /* Entry */
319 item=gtk_entry_new();
320 g_signal_connect(item, "changed", G_CALLBACK(filter_te_syntax_check_cb), NULL);
321 g_object_set_data(G_OBJECT(item_box), E_FILT_AUTOCOMP_PTR_KEY, NULL);
322 g_signal_connect(item, "key-press-event", G_CALLBACK (filter_string_te_key_pressed_cb), NULL);
323 g_signal_connect(current_dlg->dlg, "key-press-event", G_CALLBACK (filter_parent_dlg_key_pressed_cb), NULL);
324 g_object_set_data(G_OBJECT(filter_bt), E_FILT_TE_PTR_KEY, item);
326 filter=gtk_entry_get_text(GTK_ENTRY(main_display_filter_widget));
327 if(filter){
328 gtk_entry_set_text(GTK_ENTRY(item), filter);
329 } else {
330 colorize_filter_te_as_empty(item);
332 break;
334 default:
335 g_assert_not_reached();
336 item=NULL;
337 break;
340 gtk_box_pack_start(GTK_BOX(item_box), item, TRUE, TRUE, 0);
341 current_dlg->param_items[i]=item;
342 gtk_widget_show(item);
344 gtk_box_pack_start(GTK_BOX(dlg_box), item_box, TRUE, TRUE, 0);
345 gtk_widget_show(item_box);
348 /* button box */
349 bbox = dlg_button_row_new(WIRESHARK_STOCK_CREATE_STAT, GTK_STOCK_CANCEL, NULL);
350 gtk_box_pack_start(GTK_BOX(dlg_box), bbox, FALSE, FALSE, 0);
351 gtk_widget_show(bbox);
353 start_button = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), WIRESHARK_STOCK_CREATE_STAT);
354 g_signal_connect(start_button, "clicked",
355 G_CALLBACK(tap_param_dlg_start_button_clicked), current_dlg);
357 cancel_button = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CANCEL);
358 window_set_cancel_button(current_dlg->dlg, cancel_button, window_cancel_button_cb);
360 /* Catch the "activate" signal on all the text entries, so that
361 if the user types Return there, we act as if the "Create Stat"
362 button had been selected, as happens if Return is typed if
363 some widget that *doesn't* handle the Return key has the input
364 focus. */
365 for(i=0;i<current_dlg->cont.nparams;i++){
366 switch (current_dlg->cont.params[i].type) {
368 case PARAM_UINT:
369 case PARAM_ENUM:
370 break;
372 case PARAM_STRING:
373 case PARAM_FILTER:
374 dlg_set_activate(current_dlg->param_items[i], start_button);
375 break;
379 /* Give the initial focus to the first entry box. */
380 if(current_dlg->cont.nparams>0){
381 gtk_widget_grab_focus(current_dlg->param_items[0]);
384 gtk_widget_grab_default(start_button );
386 g_signal_connect(current_dlg->dlg, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
387 g_signal_connect(current_dlg->dlg, "destroy", G_CALLBACK(dlg_destroy_cb), current_dlg);
389 gtk_widget_show_all(current_dlg->dlg);
390 window_present(current_dlg->dlg);