2 * Routines for "find frame" window
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
34 #include <epan/proto.h>
35 #include <epan/dfilter/dfilter.h>
36 #include <epan/strutil.h>
37 #include <epan/prefs.h>
39 #include "../globals.h"
40 #include "../alert_box.h"
41 #include "../simple_dialog.h"
42 #include "../main_statusbar.h"
44 #include "gtk/gui_utils.h"
45 #include "gtk/find_dlg.h"
46 #include "gtk/filter_dlg.h"
47 #include "gtk/dlg_utils.h"
48 #include "gtk/stock_icons.h"
49 #include "gtk/prefs_dlg.h"
51 #include "gtk/help_dlg.h"
52 #include "gtk/filter_autocomplete.h"
54 /* Capture callback data keys */
55 #define E_FIND_FILT_KEY "find_filter_te"
56 #define E_FIND_BACKWARD_KEY "find_backward"
57 #define E_FIND_HEXDATA_KEY "find_hex"
58 #define E_FIND_STRINGDATA_KEY "find_string"
59 #define E_FIND_FILTERDATA_KEY "find_filter"
60 #define E_FIND_STRINGTYPE_KEY "find_string_type"
61 #define E_FIND_STRINGTYPE_LABEL_KEY "find_string_type_label"
62 #define E_CASE_SEARCH_KEY "case_insensitive_search"
63 #define E_SOURCE_HEX_KEY "hex_data_source"
64 #define E_SOURCE_DECODE_KEY "decode_data_source"
65 #define E_SOURCE_SUMMARY_KEY "summary_data_source"
66 #define E_FILT_TE_BUTTON_KEY "find_filter_button"
68 static gboolean case_type = TRUE;
69 static gboolean summary_data = FALSE;
70 static gboolean decode_data = FALSE;
73 find_filter_te_syntax_check_cb(GtkWidget *w, gpointer parent_w);
76 find_frame_ok_cb(GtkWidget *ok_bt, gpointer parent_w);
79 find_frame_close_cb(GtkWidget *close_bt, gpointer parent_w);
82 find_frame_destroy_cb(GtkWidget *win, gpointer user_data);
85 hex_selected_cb(GtkWidget *button_rb _U_, gpointer parent_w);
88 string_selected_cb(GtkWidget *button_rb _U_, gpointer parent_w);
91 filter_selected_cb(GtkWidget *button_rb _U_, gpointer parent_w);
94 * Keep a static pointer to the current "Find Packet" window, if any, so
95 * that if somebody tries to do "Find Packet" while there's already a
96 * "Find Packet" window up, we just pop up the existing one, rather than
99 static GtkWidget *find_frame_w;
100 static GtkWidget *filter_text_box;
103 * Save the presskey handlers to be able to dissable the auto-completion
104 * feature for hex and string searches.
106 static gulong te_presskey_handler_id;
107 static gulong win_presskey_handler_id;
110 find_frame_cb(GtkWidget *w _U_, gpointer d _U_)
112 GtkWidget *main_vb, *main_find_hb, *main_options_hb,
114 *find_type_frame, *find_type_vb,
115 *find_type_hb, *find_type_lb, *hex_rb, *string_rb, *filter_rb,
116 *filter_hb, *filter_bt,
118 *direction_frame, *direction_vb,
121 *data_frame, *data_vb,
122 *hex_data_rb, *decode_data_rb, *summary_data_rb,
124 *string_opt_frame, *string_opt_vb,
125 *case_cb, *combo_lb, *combo_cb,
127 *bbox, *ok_bt, *cancel_bt, *help_bt;
128 GtkTooltips *tooltips;
131 /* No Apply button, but "OK" not only sets our text widget, it
132 activates it (i.e., it causes us to do the search). */
133 static construct_args_t args = {
134 "Wireshark: Search Filter",
140 if (find_frame_w != NULL) {
141 /* There's already a "Find Packet" dialog box; reactivate it. */
142 reactivate_window(find_frame_w);
146 find_frame_w = dlg_window_new("Wireshark: Find Packet");
147 tooltips = gtk_tooltips_new ();
149 /* Container for each row of widgets */
150 main_vb = gtk_vbox_new(FALSE, 3);
151 gtk_container_set_border_width(GTK_CONTAINER(main_vb), 5);
152 gtk_container_add(GTK_CONTAINER(find_frame_w), main_vb);
153 gtk_widget_show(main_vb);
157 main_find_hb = gtk_hbox_new(FALSE, 3);
158 gtk_container_add(GTK_CONTAINER(main_vb), main_find_hb);
159 gtk_widget_show(main_find_hb);
163 find_type_frame = gtk_frame_new("Find");
164 gtk_box_pack_start(GTK_BOX(main_find_hb), find_type_frame, TRUE, TRUE, 0);
165 gtk_widget_show(find_type_frame);
167 find_type_vb = gtk_vbox_new(FALSE, 3);
168 gtk_container_set_border_width(GTK_CONTAINER(find_type_vb), 3);
169 gtk_container_add(GTK_CONTAINER(find_type_frame), find_type_vb);
170 gtk_widget_show(find_type_vb);
173 find_type_hb = gtk_hbox_new(FALSE, 3);
174 gtk_container_add(GTK_CONTAINER(find_type_vb), find_type_hb);
175 gtk_widget_show(find_type_hb);
177 find_type_lb = gtk_label_new("By:");
178 gtk_box_pack_start(GTK_BOX(find_type_hb), find_type_lb, FALSE, FALSE, 0);
179 gtk_widget_show(find_type_lb);
182 filter_rb = gtk_radio_button_new_with_mnemonic_from_widget(NULL, "_Display filter");
183 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(filter_rb), !cfile.hex && !cfile.string);
184 gtk_box_pack_start(GTK_BOX(find_type_hb), filter_rb, FALSE, FALSE, 0);
185 gtk_tooltips_set_tip (tooltips, filter_rb, ("Search for data by display filter syntax.\ne.g. ip.addr==10.1.1.1"), NULL);
186 gtk_widget_show(filter_rb);
189 hex_rb = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(filter_rb), "_Hex value");
190 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(hex_rb), cfile.hex);
191 gtk_box_pack_start(GTK_BOX(find_type_hb), hex_rb, FALSE, FALSE, 0);
192 gtk_tooltips_set_tip (tooltips, hex_rb, ("Search for data by hex string.\ne.g. fffffda5"), NULL);
193 gtk_widget_show(hex_rb);
196 string_rb = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(filter_rb), "_String");
197 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(string_rb), cfile.string);
198 gtk_box_pack_start(GTK_BOX(find_type_hb), string_rb, FALSE, FALSE, 0);
199 gtk_tooltips_set_tip (tooltips, string_rb, ("Search for data by string value.\ne.g. My String"), NULL);
200 gtk_widget_show(string_rb);
203 filter_hb = gtk_hbox_new(FALSE, 3);
204 gtk_box_pack_start(GTK_BOX(find_type_vb), filter_hb, FALSE, FALSE, 0);
205 gtk_widget_show(filter_hb);
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), &args);
209 g_signal_connect(filter_bt, "destroy", G_CALLBACK(filter_button_destroy_cb), NULL);
210 g_object_set_data(G_OBJECT(filter_bt), E_FILT_TE_BUTTON_KEY, filter_bt);
211 gtk_box_pack_start(GTK_BOX(filter_hb), filter_bt, FALSE, TRUE, 0);
212 gtk_tooltips_set_tip (tooltips, filter_bt, ("Click on the filter button to select a display filter,\nor enter your search criteria into the text box"), NULL);
213 gtk_widget_show(filter_bt);
215 filter_text_box = gtk_entry_new();
216 if (cfile.sfilter) gtk_entry_set_text(GTK_ENTRY(filter_text_box), cfile.sfilter);
217 g_object_set_data(G_OBJECT(filter_bt), E_FILT_TE_PTR_KEY, filter_text_box);
218 g_object_set_data(G_OBJECT(find_frame_w), E_FILT_TE_PTR_KEY, filter_text_box);
219 gtk_box_pack_start(GTK_BOX(filter_hb), filter_text_box, TRUE, TRUE, 0);
220 g_signal_connect(filter_text_box, "changed", G_CALLBACK(find_filter_te_syntax_check_cb), find_frame_w);
221 g_object_set_data(G_OBJECT(find_frame_w), E_FILT_AUTOCOMP_PTR_KEY, NULL);
222 te_presskey_handler_id = g_signal_connect(filter_text_box, "key-press-event", G_CALLBACK (filter_string_te_key_pressed_cb), NULL);
223 win_presskey_handler_id = g_signal_connect(find_frame_w, "key-press-event", G_CALLBACK (filter_parent_dlg_key_pressed_cb), NULL);
224 gtk_widget_show(filter_text_box);
228 main_options_hb = gtk_hbox_new(FALSE, 3);
229 gtk_container_add(GTK_CONTAINER(main_vb), main_options_hb);
230 gtk_widget_show(main_options_hb);
233 /* search in frame */
234 data_frame = gtk_frame_new("Search In");
235 gtk_box_pack_start(GTK_BOX(main_options_hb), data_frame, TRUE, TRUE, 0);
236 gtk_widget_show(data_frame);
239 data_vb = gtk_vbox_new(TRUE, 0);
240 gtk_container_set_border_width(GTK_CONTAINER(data_vb), 3);
241 gtk_container_add(GTK_CONTAINER(data_frame), data_vb);
242 gtk_widget_show(data_vb);
245 summary_data_rb = gtk_radio_button_new_with_mnemonic_from_widget(NULL, "Packet list");
246 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(summary_data_rb), summary_data);
247 gtk_box_pack_start(GTK_BOX(data_vb), summary_data_rb, TRUE, TRUE, 0);
248 gtk_tooltips_set_tip (tooltips, summary_data_rb, ("Search for string in the Info column of the packet summary (top pane)"), NULL);
249 gtk_widget_show(summary_data_rb);
252 decode_data_rb = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(summary_data_rb), "Packet details");
253 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(decode_data_rb), decode_data);
254 gtk_box_pack_start(GTK_BOX(data_vb), decode_data_rb, TRUE, TRUE, 0);
255 gtk_tooltips_set_tip (tooltips, decode_data_rb, ("Search for string in the decoded packet display (middle pane)"), NULL);
256 gtk_widget_show(decode_data_rb);
259 hex_data_rb = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(summary_data_rb), "Packet bytes");
260 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(hex_data_rb), !decode_data && !summary_data);
261 gtk_box_pack_start(GTK_BOX(data_vb), hex_data_rb, TRUE, TRUE, 0);
262 gtk_tooltips_set_tip (tooltips, hex_data_rb, ("Search for string in the packet data"), NULL);
263 gtk_widget_show(hex_data_rb);
265 /* string options frame */
266 string_opt_frame = gtk_frame_new("String Options");
267 gtk_box_pack_start(GTK_BOX(main_options_hb), string_opt_frame, TRUE, TRUE, 0);
268 gtk_widget_show(string_opt_frame);
270 string_opt_vb = gtk_vbox_new(FALSE, 0);
271 gtk_container_add(GTK_CONTAINER(string_opt_frame), string_opt_vb);
272 gtk_container_set_border_width(GTK_CONTAINER(string_opt_vb), 3);
273 gtk_widget_show(string_opt_vb);
275 case_cb = gtk_check_button_new_with_mnemonic("Case sensitive");
276 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(case_cb), !case_type);
277 gtk_container_add(GTK_CONTAINER(string_opt_vb), case_cb);
278 gtk_tooltips_set_tip (tooltips, case_cb, ("Search by mixed upper/lower case?"), NULL);
279 gtk_widget_show(case_cb);
281 combo_lb = gtk_label_new("Character set:");
282 gtk_container_add(GTK_CONTAINER(string_opt_vb), combo_lb);
283 gtk_misc_set_alignment(GTK_MISC(combo_lb), 0.0f, 0.5f);
284 gtk_widget_show(combo_lb);
286 /* Character Type Selection Dropdown Box
287 These only apply to the string find option */
288 /* Create Combo Box */
290 combo_cb = gtk_combo_box_new_text();
292 gtk_combo_box_append_text(GTK_COMBO_BOX(combo_cb), "ASCII Unicode & Non-Unicode");
293 gtk_combo_box_append_text(GTK_COMBO_BOX(combo_cb), "ASCII Non-Unicode");
294 gtk_combo_box_append_text(GTK_COMBO_BOX(combo_cb), "ASCII Unicode");
296 gtk_combo_box_set_active(GTK_COMBO_BOX(combo_cb),0);
297 gtk_container_add(GTK_CONTAINER(string_opt_vb), combo_cb);
299 gtk_widget_show(combo_cb);
302 /* direction frame */
303 direction_frame = gtk_frame_new("Direction");
304 gtk_box_pack_start(GTK_BOX(main_options_hb), direction_frame, FALSE, FALSE, 0);
305 gtk_widget_show(direction_frame);
307 /* Direction row: Forward and reverse radio buttons */
308 direction_vb = gtk_vbox_new(FALSE, 0);
309 gtk_container_set_border_width(GTK_CONTAINER(direction_vb), 3);
310 gtk_container_add(GTK_CONTAINER(direction_frame), direction_vb);
311 gtk_widget_show(direction_vb);
313 up_rb = gtk_radio_button_new_with_mnemonic_from_widget(NULL, "_Up");
314 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(up_rb), cfile.dir == SD_BACKWARD);
315 gtk_box_pack_start(GTK_BOX(direction_vb), up_rb, FALSE, FALSE, 0);
316 gtk_widget_show(up_rb);
318 down_rb = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(up_rb), "_Down");
319 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(down_rb), cfile.dir == SD_FORWARD);
320 gtk_box_pack_start(GTK_BOX(direction_vb), down_rb, FALSE, FALSE, 0);
321 gtk_widget_show(down_rb);
325 bbox = dlg_button_row_new(GTK_STOCK_FIND, GTK_STOCK_CANCEL, GTK_STOCK_HELP, NULL);
326 gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE, FALSE, 0);
327 gtk_widget_show(bbox);
329 ok_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_FIND);
330 g_signal_connect(ok_bt, "clicked", G_CALLBACK(find_frame_ok_cb), find_frame_w);
332 cancel_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CANCEL);
333 g_signal_connect(cancel_bt, "clicked", G_CALLBACK(find_frame_close_cb), find_frame_w);
335 help_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_HELP);
336 g_signal_connect(help_bt, "clicked", G_CALLBACK(topic_cb), (gpointer)HELP_FIND_DIALOG);
338 /* Attach pointers to needed widgets to the capture prefs window/object */
339 g_object_set_data(G_OBJECT(find_frame_w), E_FIND_FILT_KEY, filter_text_box);
340 g_object_set_data(G_OBJECT(find_frame_w), E_FIND_BACKWARD_KEY, up_rb);
341 g_object_set_data(G_OBJECT(find_frame_w), E_FIND_FILTERDATA_KEY, filter_rb);
342 g_object_set_data(G_OBJECT(find_frame_w), E_FIND_HEXDATA_KEY, hex_rb);
343 g_object_set_data(G_OBJECT(find_frame_w), E_FIND_STRINGDATA_KEY, string_rb);
344 g_object_set_data(G_OBJECT(find_frame_w), E_FIND_STRINGTYPE_LABEL_KEY, combo_lb);
345 g_object_set_data(G_OBJECT(find_frame_w), E_FIND_STRINGTYPE_KEY, combo_cb);
346 g_object_set_data(G_OBJECT(find_frame_w), E_CASE_SEARCH_KEY, case_cb);
347 g_object_set_data(G_OBJECT(find_frame_w), E_SOURCE_HEX_KEY, hex_data_rb);
348 g_object_set_data(G_OBJECT(find_frame_w), E_SOURCE_DECODE_KEY, decode_data_rb);
349 g_object_set_data(G_OBJECT(find_frame_w), E_SOURCE_SUMMARY_KEY, summary_data_rb);
350 g_object_set_data(G_OBJECT(find_frame_w), E_FILT_TE_BUTTON_KEY, filter_bt);
353 * Now that we've attached the pointers, connect the signals - if
354 * we do so before we've attached the pointers, the signals may
355 * be delivered before the pointers are attached; the signal
356 * handlers expect the pointers to be attached, and won't be happy.
358 g_signal_connect(hex_rb, "clicked", G_CALLBACK(hex_selected_cb), find_frame_w);
359 g_signal_connect(string_rb, "clicked", G_CALLBACK(string_selected_cb), find_frame_w);
360 g_signal_connect(filter_rb, "clicked", G_CALLBACK(filter_selected_cb), find_frame_w);
362 string_selected_cb(NULL, find_frame_w);
363 filter_selected_cb(NULL, find_frame_w);
365 window_set_cancel_button(find_frame_w, cancel_bt, window_cancel_button_cb);
367 gtk_widget_grab_default(ok_bt);
369 /* Catch the "activate" signal on the filter text entry, so that
370 if the user types Return there, we act as if the "OK" button
371 had been selected, as happens if Return is typed if some widget
372 that *doesn't* handle the Return key has the input focus. */
373 dlg_set_activate(filter_text_box, ok_bt);
375 /* Give the initial focus to the "Filter" entry box. */
376 gtk_widget_grab_focus(filter_text_box);
378 g_signal_connect(find_frame_w, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
379 g_signal_connect(find_frame_w, "destroy", G_CALLBACK(find_frame_destroy_cb), NULL);
381 gtk_widget_show(find_frame_w);
382 window_present(find_frame_w);
385 /* this function opens the find frame dialogue and sets the filter string */
387 find_frame_with_filter(char *filter)
389 find_frame_cb(NULL, NULL);
390 gtk_entry_set_text(GTK_ENTRY(filter_text_box), filter);
394 * Check the filter syntax based on the type of search we're doing.
397 find_filter_te_syntax_check_cb(GtkWidget *w, gpointer parent_w)
400 GtkWidget *hex_rb, *string_rb;
401 guint8 *bytes = NULL;
404 hex_rb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_FIND_HEXDATA_KEY);
405 string_rb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_FIND_STRINGDATA_KEY);
407 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (hex_rb))) {
409 * Hex search - scan the search string to make sure it's valid hex.
411 strval = gtk_entry_get_text(GTK_ENTRY(w));
412 if (strval == NULL) {
413 /* XXX - can this happen? */
414 colorize_filter_te_as_invalid(w);
416 bytes = convert_string_to_hex(strval, &nbytes);
418 colorize_filter_te_as_invalid(w);
421 colorize_filter_te_as_valid(w);
424 } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (string_rb))) {
426 * String search. Make sure the string isn't empty.
428 strval = gtk_entry_get_text(GTK_ENTRY(w));
429 if (strval == NULL) {
430 /* XXX - can this happen? */
431 colorize_filter_te_as_invalid(w);
433 if (strcmp(strval, "") == 0)
434 colorize_filter_te_as_invalid(w);
436 colorize_filter_te_as_valid(w);
440 * Display filter search; check it with "filter_te_syntax_check_cb()".
442 filter_te_syntax_check_cb(w, NULL);
447 * This function will re-check the search text syntax.
450 hex_selected_cb(GtkWidget *button_rb _U_, gpointer parent_w)
452 GtkWidget *filter_tb, *hex_rb;
454 filter_tb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_FILT_TE_PTR_KEY);
455 hex_rb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_FIND_HEXDATA_KEY);
457 /* Disable AutoCompletion feature */
458 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(hex_rb)) && g_signal_handler_is_connected(filter_tb, te_presskey_handler_id)) {
459 g_signal_handler_disconnect(filter_tb, te_presskey_handler_id);
460 g_signal_handler_disconnect(parent_w, win_presskey_handler_id);
463 /* Re-check the display filter. */
464 find_filter_te_syntax_check_cb(filter_tb, parent_w);
469 * This function will disable the string options until
470 * the string search is selected.
473 string_selected_cb(GtkWidget *button_rb _U_, gpointer parent_w)
475 GtkWidget *string_rb, *hex_data_rb, *decode_data_rb, *summary_data_rb,
476 *data_combo_lb, *data_combo_cb, *data_case_cb, *filter_tb;
478 string_rb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_FIND_STRINGDATA_KEY);
479 hex_data_rb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_SOURCE_HEX_KEY);
480 decode_data_rb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_SOURCE_DECODE_KEY);
481 summary_data_rb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_SOURCE_SUMMARY_KEY);
483 data_combo_lb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_FIND_STRINGTYPE_LABEL_KEY);
484 data_combo_cb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_FIND_STRINGTYPE_KEY);
485 data_case_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CASE_SEARCH_KEY);
486 filter_tb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_FILT_TE_PTR_KEY);
488 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(string_rb))) {
489 gtk_widget_set_sensitive(GTK_WIDGET(hex_data_rb), TRUE);
490 gtk_widget_set_sensitive(GTK_WIDGET(decode_data_rb), TRUE);
491 gtk_widget_set_sensitive(GTK_WIDGET(summary_data_rb), TRUE);
492 gtk_widget_set_sensitive(GTK_WIDGET(data_combo_lb), TRUE);
493 gtk_widget_set_sensitive(GTK_WIDGET(data_combo_cb), TRUE);
494 gtk_widget_set_sensitive(GTK_WIDGET(data_case_cb), TRUE);
496 /* Disable AutoCompletion feature */
497 if(g_signal_handler_is_connected(filter_tb, te_presskey_handler_id)) {
498 g_signal_handler_disconnect(filter_tb, te_presskey_handler_id);
499 g_signal_handler_disconnect(parent_w, win_presskey_handler_id);
503 gtk_widget_set_sensitive(GTK_WIDGET(hex_data_rb), FALSE);
504 gtk_widget_set_sensitive(GTK_WIDGET(decode_data_rb), FALSE);
505 gtk_widget_set_sensitive(GTK_WIDGET(summary_data_rb), FALSE);
506 gtk_widget_set_sensitive(GTK_WIDGET(data_combo_lb), FALSE);
507 gtk_widget_set_sensitive(GTK_WIDGET(data_combo_cb), FALSE);
508 gtk_widget_set_sensitive(GTK_WIDGET(data_case_cb), FALSE);
510 /* Re-check the display filter. */
511 find_filter_te_syntax_check_cb(filter_tb, parent_w);
516 * This function will disable the filter button until
517 * the filter search is selected.
520 filter_selected_cb(GtkWidget *button_rb _U_, gpointer parent_w)
522 GtkWidget *filter_bt, *filter_rb, *filter_te;
524 filter_bt = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_FILT_TE_BUTTON_KEY);
525 filter_rb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_FIND_FILTERDATA_KEY);
526 filter_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_FILT_TE_PTR_KEY);
528 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(filter_rb)))
530 gtk_widget_set_sensitive(GTK_WIDGET(filter_bt), TRUE);
531 /* Enable AutoCompletion feature */
532 if(!g_signal_handler_is_connected(filter_te, te_presskey_handler_id)) {
533 te_presskey_handler_id = g_signal_connect(filter_te, "key-press-event", G_CALLBACK (filter_string_te_key_pressed_cb), NULL);
534 win_presskey_handler_id = g_signal_connect(parent_w, "key-press-event", G_CALLBACK (filter_parent_dlg_key_pressed_cb), NULL);
539 gtk_widget_set_sensitive(GTK_WIDGET(filter_bt), FALSE);
545 find_frame_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w)
547 GtkWidget *filter_te, *up_rb, *hex_rb, *string_rb, *combo_cb,
548 *case_cb, *decode_data_rb, *summary_data_rb;
549 const gchar *filter_text;
550 search_charset_t scs_type = SCS_ASCII_AND_UNICODE;
551 guint8 *bytes = NULL;
554 dfilter_t *sfcode = NULL;
555 gboolean found_packet=FALSE;
558 filter_te = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_FIND_FILT_KEY);
559 up_rb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_FIND_BACKWARD_KEY);
560 hex_rb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_FIND_HEXDATA_KEY);
561 string_rb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_FIND_STRINGDATA_KEY);
562 combo_cb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_FIND_STRINGTYPE_KEY);
563 case_cb = (GtkWidget *) g_object_get_data(G_OBJECT(parent_w), E_CASE_SEARCH_KEY);
564 decode_data_rb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_SOURCE_DECODE_KEY);
565 summary_data_rb = (GtkWidget *)g_object_get_data(G_OBJECT(parent_w), E_SOURCE_SUMMARY_KEY);
567 filter_text = gtk_entry_get_text(GTK_ENTRY(filter_te));
569 /* Corresponds to the enum in file.c
570 * Character set for text search.
572 * SCS_ASCII_AND_UNICODE,
575 * / * add EBCDIC when it's implemented * /
576 * } search_charset_t;
578 string_type = gtk_combo_box_get_active (GTK_COMBO_BOX(combo_cb));
580 case_type = !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(case_cb));
581 decode_data = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(decode_data_rb));
582 summary_data = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(summary_data_rb));
585 * Process the search criterion.
587 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (hex_rb))) {
589 * Hex search - scan the search string to make sure it's valid hex
590 * and to find out how many bytes there are.
592 bytes = convert_string_to_hex(filter_text, &nbytes);
594 statusbar_push_temporary_msg("That's not a valid hex string.");
597 } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (string_rb))) {
600 * Make sure we're searching for something, first.
602 if (strcmp(filter_text, "") == 0) {
603 statusbar_push_temporary_msg("You didn't specify any text for which to search.");
608 * We are - get the character set type.
610 if (string_type == SCS_ASCII_AND_UNICODE)
611 scs_type = SCS_ASCII_AND_UNICODE;
612 else if (string_type == SCS_ASCII)
613 scs_type = SCS_ASCII;
614 else if (string_type == SCS_UNICODE)
615 scs_type = SCS_UNICODE;
617 statusbar_push_temporary_msg("You didn't choose a valid character set.");
620 string = convert_string_case(filter_text, case_type);
623 * Display filter search - try to compile the filter.
625 if (!dfilter_compile(filter_text, &sfcode)) {
626 /* The attempt failed; report an error. */
627 bad_dfilter_alert_box(filter_text);
632 if (sfcode == NULL) {
633 /* Yes - complain. */
634 statusbar_push_temporary_msg("That filter doesn't test anything.");
640 * Remember the search parameters.
642 g_free(cfile.sfilter);
643 cfile.sfilter = g_strdup(filter_text);
644 cfile.dir = GTK_TOGGLE_BUTTON (up_rb)->active ? SD_BACKWARD : SD_FORWARD;
645 cfile.hex = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (hex_rb));
646 cfile.string = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (string_rb));
647 cfile.scs_type = scs_type;
648 cfile.case_type = case_type;
649 cfile.decode_data = decode_data;
650 cfile.summary_data = summary_data;
653 found_packet = cf_find_packet_data(&cfile, bytes, nbytes, cfile.dir);
656 /* We didn't find a packet */
657 statusbar_push_temporary_msg("No packet contained those bytes.");
660 } else if (cfile.string) {
661 /* OK, what are we searching? */
662 if (cfile.decode_data) {
663 /* The text in the protocol tree */
665 found_packet = cf_find_packet_protocol_tree(&cfile, string, cfile.dir);
669 /* We didn't find the packet. */
670 statusbar_push_temporary_msg("No packet contained that string in its dissected display.");
673 } else if (cfile.summary_data) {
674 /* The text in the summary line */
676 found_packet = cf_find_packet_summary_line(&cfile, string, cfile.dir);
680 /* We didn't find the packet. */
681 simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
682 "%sNo match found!%s\n\n"
683 "No packet contained that string in its Info column.",
684 simple_dialog_primary_start(), simple_dialog_primary_end());
688 /* The raw packet data */
690 found_packet = cf_find_packet_data(&cfile, string, strlen(string),
695 /* We didn't find the packet. */
696 statusbar_push_temporary_msg("No packet contained that string in its data.");
701 found_packet = cf_find_packet_dfilter(&cfile, sfcode, cfile.dir);
702 dfilter_free(sfcode);
704 /* We didn't find a packet */
705 statusbar_push_temporary_msg("No packet matched that filter.");
710 window_destroy(GTK_WIDGET(parent_w));
714 find_frame_close_cb(GtkWidget *close_bt _U_, gpointer parent_w)
716 gtk_grab_remove(GTK_WIDGET(parent_w));
717 window_destroy(GTK_WIDGET(parent_w));
721 find_frame_destroy_cb(GtkWidget *win _U_, gpointer user_data _U_)
723 /* Note that we no longer have a "Find Packet" dialog box. */
728 find_previous_next(GtkWidget *w, gpointer d, search_direction dir)
738 bytes = convert_string_to_hex(cfile.sfilter, &nbytes);
741 * XXX - this shouldn't happen, as we've already successfully
742 * translated the string once.
746 cf_find_packet_data(&cfile, bytes, nbytes, dir);
748 } else if (cfile.string) {
749 string = convert_string_case(cfile.sfilter, cfile.case_type);
750 /* OK, what are we searching? */
751 if (cfile.decode_data) {
752 /* The text in the protocol tree */
753 cf_find_packet_protocol_tree(&cfile, string, dir);
754 } else if (cfile.summary_data) {
755 /* The text in the summary line */
756 cf_find_packet_summary_line(&cfile, string, dir);
758 /* The raw packet data */
759 cf_find_packet_data(&cfile, string, strlen(string), dir);
763 if (!dfilter_compile(cfile.sfilter, &sfcode)) {
765 * XXX - this shouldn't happen, as we've already successfully
766 * translated the string once.
770 if (sfcode == NULL) {
772 * XXX - this shouldn't happen, as we've already found that the
773 * string wasn't null.
777 cf_find_packet_dfilter(&cfile, sfcode, dir);
778 dfilter_free(sfcode);
785 find_next_cb(GtkWidget *w , gpointer d)
787 find_previous_next(w, d, SD_FORWARD);
791 find_previous_cb(GtkWidget *w , gpointer d)
793 find_previous_next(w, d, SD_BACKWARD);