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
:
104 case REGISTER_STAT_GROUP_TELEPHONY_SCTP
:
107 case REGISTER_TOOLS_GROUP_UNSORTED
:
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 */
118 tap_param_dlg_cb
, /* Callback */
119 info
, /* Callback data */
125 void tap_param_dlg_update (void)
127 tap_param_dlg_list_item
*dialog
= start_dlg_list
;
131 while(dialog
!= NULL
) {
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
);
139 dialog
= dialog
->next
;
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
;
151 tap_param_dlg_start_button_clicked(GtkWidget
*item _U_
, gpointer dialog_data
)
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
) {
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
);
172 d
= gtk_spin_button_get_value(GTK_SPIN_BUTTON(dlg_data
->param_items
[i
]));
173 g_string_append_printf(params
,"%u",(guint
)d
);
178 g_string_append(params
,
179 gtk_entry_get_text(GTK_ENTRY(dlg_data
->param_items
[i
])));
183 (dlg_data
->cont
.tap_init_cb
)(params
->str
,NULL
);
184 g_string_free(params
, TRUE
);
188 tap_param_dlg_cb(GtkAction
*action _U_
, gpointer data
)
194 GtkWidget
*item_box
, *item
, *label
, *filter_bt
;
195 GtkWidget
*bbox
, *start_button
, *cancel_button
;
197 char *label_with_colon
;
199 tap_param_dlg
*dlg_data
= (tap_param_dlg
*) data
;
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 */
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
;
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 */
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
));
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);
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
++) {
264 item_box
=ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 3, FALSE
);
266 switch (current_dlg
->cont
.params
[i
].type
) {
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
);
277 item
=gtk_spin_button_new_with_range(0, G_MAXUINT
, 1);
278 gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(item
), TRUE
);
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
);
291 item
=gtk_entry_new();
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
);
303 item
=gtk_combo_box_text_new();
304 for (j
= 0; current_dlg
->cont
.params
[i
].enum_vals
[j
].name
!= NULL
;
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);
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
);
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
));
328 gtk_entry_set_text(GTK_ENTRY(item
), filter
);
330 colorize_filter_te_as_empty(item
);
335 g_assert_not_reached();
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
);
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
365 for(i
=0;i
<current_dlg
->cont
.nparams
;i
++){
366 switch (current_dlg
->cont
.params
[i
].type
) {
374 dlg_set_activate(current_dlg
->param_items
[i
], start_button
);
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
);