carve out the (currently disabled) welcome page into it's own file to slightly reduce...
[obnox/wireshark/wip.git] / gtk / range_utils.c
1 /* range_utils.c
2  * Packet range routines (save, print, ...) for GTK things
3  *
4  * $Id$
5  *
6  * Ulf Lamping <ulf.lamping@web.de>
7  *
8  * Wireshark - Network traffic analyzer
9  * By Gerald Combs <gerald@wireshark.org>
10  * Copyright 1998 Gerald Combs
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  */
26
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include <gtk/gtk.h>
32
33 #include "globals.h"
34
35 #include "packet-range.h"
36 #include "gui_utils.h"
37 #include "dlg_utils.h"
38 #include "compat_macros.h"
39 #include "simple_dialog.h"
40 #include "range_utils.h"
41
42
43 #define RANGE_VALUES_KEY                "range_values"
44 #define RANGE_CAPTURED_BT_KEY           "range_captured_button"
45 #define RANGE_DISPLAYED_BT_KEY          "range_displayed_button"
46
47 #define RANGE_SELECT_ALL_KEY            "range_select_all_rb"
48 #define RANGE_SELECT_ALL_C_KEY          "range_select_all_c_lb"
49 #define RANGE_SELECT_ALL_D_KEY          "range_select_all_d_lb"
50 #define RANGE_SELECT_CURR_KEY           "range_select_curr_rb"
51 #define RANGE_SELECT_CURR_C_KEY         "range_select_curr_c_lb"
52 #define RANGE_SELECT_CURR_D_KEY         "range_select_curr_d_lb"
53 #define RANGE_SELECT_MARKED_KEY         "range_select_marked_only_rb"
54 #define RANGE_SELECT_MARKED_C_KEY       "range_select_marked_only_c_lb"
55 #define RANGE_SELECT_MARKED_D_KEY       "range_select_marked_only_d_lb"
56 #define RANGE_SELECT_MARKED_RANGE_KEY   "range_select_marked_range_rb"
57 #define RANGE_SELECT_MARKED_RANGE_C_KEY "range_select_marked_range_c_lb"
58 #define RANGE_SELECT_MARKED_RANGE_D_KEY "range_select_marked_range_d_lb"
59 #define RANGE_SELECT_USER_KEY           "range_select_user_range_rb"
60 #define RANGE_SELECT_USER_C_KEY         "range_select_user_range_c_lb"
61 #define RANGE_SELECT_USER_D_KEY         "range_select_user_range_d_lb"
62 #define RANGE_SELECT_USER_ENTRY_KEY     "range_select_user_range_entry"
63
64 gboolean
65 range_check_validity(packet_range_t *range)
66 {
67   switch (packet_range_check(range)) {
68
69   case CVT_NO_ERROR:
70     return TRUE;
71
72   case CVT_SYNTAX_ERROR:
73     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
74       "The specified range of packets isn't a valid range.");
75     return FALSE;
76
77   case CVT_NUMBER_TOO_BIG:
78     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
79       "The specified range of packets has a packet number that's too large.");
80     return FALSE;
81
82   default:
83     g_assert_not_reached();
84     return FALSE;
85   }
86 }
87
88 /* update all "dynamic" things */
89 void
90 range_update_dynamics(gpointer data)
91 {
92   packet_range_t *range;
93   GtkWidget     *range_displayed_bt;
94   gboolean      filtered_active;
95   gint          selected_num;
96   gboolean      can_select;
97   gchar         label_text[100];
98
99
100   range = OBJECT_GET_DATA(data, RANGE_VALUES_KEY);
101
102   
103   range_displayed_bt = OBJECT_GET_DATA(data, RANGE_DISPLAYED_BT_KEY);
104   filtered_active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(range_displayed_bt));
105
106   /* Enable saving only the displayed packets only if there *are*
107      displayed packets. */
108   if (range->displayed_cnt != 0)
109     gtk_widget_set_sensitive(range_displayed_bt, TRUE);
110   else {
111     /* If saving the displayed packets is selected, select saving the
112        captured packets. */
113     filtered_active = FALSE;
114     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(OBJECT_GET_DATA(data, RANGE_SELECT_ALL_KEY)), FALSE);
115     gtk_widget_set_sensitive(range_displayed_bt, FALSE);
116   }
117
118   gtk_widget_set_sensitive(OBJECT_GET_DATA(data, RANGE_SELECT_ALL_C_KEY), !filtered_active);
119   g_snprintf(label_text, sizeof(label_text), "%u", cfile.count);
120   gtk_label_set_text(GTK_LABEL(OBJECT_GET_DATA(data, RANGE_SELECT_ALL_C_KEY)), label_text);
121   gtk_widget_set_sensitive(OBJECT_GET_DATA(data, RANGE_SELECT_ALL_D_KEY), filtered_active);
122   g_snprintf(label_text, sizeof(label_text), "%u", range->displayed_cnt);
123   gtk_label_set_text(GTK_LABEL(OBJECT_GET_DATA(data, RANGE_SELECT_ALL_D_KEY)), label_text);
124
125   /* Enable saving the currently-selected packet only if there *is* a
126      currently-selected packet. */
127   selected_num = (cfile.current_frame) ? cfile.current_frame->num : 0;
128   can_select = (selected_num != 0);
129   if (can_select) {
130     gtk_widget_set_sensitive(OBJECT_GET_DATA(data, RANGE_SELECT_CURR_KEY), TRUE);
131     gtk_widget_set_sensitive(OBJECT_GET_DATA(data, RANGE_SELECT_CURR_C_KEY), !filtered_active);
132     gtk_widget_set_sensitive(OBJECT_GET_DATA(data, RANGE_SELECT_CURR_D_KEY), filtered_active);
133   } else {
134     /* If "save selected packet" is selected, select "save all packets". */
135     if (range->process == range_process_selected) {
136       range->process = range_process_all;
137       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(OBJECT_GET_DATA(data, RANGE_SELECT_ALL_KEY)), TRUE);
138     }
139     gtk_widget_set_sensitive(OBJECT_GET_DATA(data, RANGE_SELECT_CURR_KEY), FALSE);
140     gtk_widget_set_sensitive(OBJECT_GET_DATA(data, RANGE_SELECT_CURR_C_KEY), FALSE);
141     gtk_widget_set_sensitive(OBJECT_GET_DATA(data, RANGE_SELECT_CURR_D_KEY), FALSE);
142   }
143   /* XXX: how to update the radio button label but keep the mnemonic? */
144 /*g_snprintf(label_text, sizeof(label_text), "_Selected packet #%u only", selected_num);
145   gtk_label_set_text(GTK_LABEL(GTK_BIN(select_curr_rb)->child), label_text);*/
146   g_snprintf(label_text, sizeof(label_text), "%u", selected_num ? 1 : 0);
147   gtk_label_set_text(GTK_LABEL(OBJECT_GET_DATA(data, RANGE_SELECT_CURR_C_KEY)), label_text);
148   g_snprintf(label_text, sizeof(label_text), "%u", selected_num ? 1 : 0);
149   gtk_label_set_text(GTK_LABEL(OBJECT_GET_DATA(data, RANGE_SELECT_CURR_D_KEY)), label_text);
150
151   /* Enable the buttons for saving marked packets only if there *are*
152      marked packets. */
153   if (filtered_active)
154     can_select = (range->displayed_marked_cnt != 0);
155   else
156     can_select = (cfile.marked_count > 0);
157   if (can_select) {
158     gtk_widget_set_sensitive(OBJECT_GET_DATA(data, RANGE_SELECT_MARKED_KEY), TRUE);
159     gtk_widget_set_sensitive(OBJECT_GET_DATA(data, RANGE_SELECT_MARKED_C_KEY), !filtered_active);
160     gtk_widget_set_sensitive(OBJECT_GET_DATA(data, RANGE_SELECT_MARKED_D_KEY), filtered_active);
161   }
162   else {
163     /* If "save marked packet" is selected, select "save all packets". */
164     if (range->process == range_process_marked) {
165       range->process = range_process_all;
166       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(OBJECT_GET_DATA(data, RANGE_SELECT_ALL_KEY)), TRUE);
167     }
168     gtk_widget_set_sensitive(OBJECT_GET_DATA(data, RANGE_SELECT_MARKED_KEY), FALSE);
169     gtk_widget_set_sensitive(OBJECT_GET_DATA(data, RANGE_SELECT_MARKED_C_KEY), FALSE);
170     gtk_widget_set_sensitive(OBJECT_GET_DATA(data, RANGE_SELECT_MARKED_D_KEY), FALSE);
171   }
172   g_snprintf(label_text, sizeof(label_text), "%u", cfile.marked_count);
173   gtk_label_set_text(GTK_LABEL(OBJECT_GET_DATA(data, RANGE_SELECT_MARKED_C_KEY)), label_text);
174   g_snprintf(label_text, sizeof(label_text), "%u", range->displayed_marked_cnt);
175   gtk_label_set_text(GTK_LABEL(OBJECT_GET_DATA(data, RANGE_SELECT_MARKED_D_KEY)), label_text);
176
177   /* Enable the buttons for saving the range of marked packets only if
178      there *is* a range of marked packets. */
179   if (filtered_active)
180     can_select = (range->displayed_mark_range_cnt != 0);
181   else
182     can_select = (range->mark_range_cnt != 0);
183   if (can_select) {
184     gtk_widget_set_sensitive(OBJECT_GET_DATA(data, RANGE_SELECT_MARKED_RANGE_KEY), TRUE);
185     gtk_widget_set_sensitive(OBJECT_GET_DATA(data, RANGE_SELECT_MARKED_RANGE_C_KEY), !filtered_active);
186     gtk_widget_set_sensitive(OBJECT_GET_DATA(data, RANGE_SELECT_MARKED_RANGE_D_KEY), filtered_active);
187   }
188   else {
189     /* If "save range between first and last marked packet" is selected,
190        select "save all packets". */
191     if (range->process == range_process_marked_range) {
192       range->process = range_process_all;
193       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(OBJECT_GET_DATA(data, RANGE_SELECT_ALL_KEY)), TRUE);
194     }
195     gtk_widget_set_sensitive(OBJECT_GET_DATA(data, RANGE_SELECT_MARKED_RANGE_KEY), FALSE);
196     gtk_widget_set_sensitive(OBJECT_GET_DATA(data, RANGE_SELECT_MARKED_RANGE_C_KEY), FALSE);
197     gtk_widget_set_sensitive(OBJECT_GET_DATA(data, RANGE_SELECT_MARKED_RANGE_D_KEY), FALSE);
198   }
199   gtk_label_set_text(GTK_LABEL(OBJECT_GET_DATA(data, RANGE_SELECT_MARKED_RANGE_C_KEY)), label_text);
200   g_snprintf(label_text, sizeof(label_text), "%u", range->displayed_mark_range_cnt);
201   gtk_label_set_text(GTK_LABEL(OBJECT_GET_DATA(data, RANGE_SELECT_MARKED_RANGE_D_KEY)), label_text);
202   g_snprintf(label_text, sizeof(label_text), "%u", range->mark_range_cnt);
203
204   gtk_widget_set_sensitive(OBJECT_GET_DATA(data, RANGE_SELECT_USER_KEY), TRUE);
205   gtk_widget_set_sensitive(OBJECT_GET_DATA(data, RANGE_SELECT_USER_C_KEY), !filtered_active);
206   gtk_widget_set_sensitive(OBJECT_GET_DATA(data, RANGE_SELECT_USER_D_KEY), filtered_active);
207   g_snprintf(label_text, sizeof(label_text), "%u", range->user_range_cnt);
208   gtk_label_set_text(GTK_LABEL(OBJECT_GET_DATA(data, RANGE_SELECT_USER_C_KEY)), label_text);
209   g_snprintf(label_text, sizeof(label_text), "%u", range->displayed_user_range_cnt);
210   gtk_label_set_text(GTK_LABEL(OBJECT_GET_DATA(data, RANGE_SELECT_USER_D_KEY)), label_text);
211 }
212
213
214 static void
215 toggle_captured_cb(GtkWidget *widget, gpointer data)
216 {
217   GtkWidget *bt;
218   packet_range_t *range;
219
220
221   range = OBJECT_GET_DATA(data, RANGE_VALUES_KEY);
222
223   /* is the button now active? */
224   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (widget))) {
225     /* They changed the state of the "captured" button. */
226     range->process_filtered = FALSE;
227
228     bt = OBJECT_GET_DATA(data, RANGE_CAPTURED_BT_KEY);
229     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bt), TRUE);
230     bt = OBJECT_GET_DATA(data, RANGE_DISPLAYED_BT_KEY);
231     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bt), FALSE);
232
233     range_update_dynamics(data);
234   }
235 }
236
237 static void
238 toggle_filtered_cb(GtkWidget *widget, gpointer data)
239 {
240   GtkWidget *bt;
241   packet_range_t *range;
242
243
244   range = OBJECT_GET_DATA(data, RANGE_VALUES_KEY);
245   
246   /* is the button now active? */
247   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (widget))) {
248     range->process_filtered = TRUE;
249     bt = OBJECT_GET_DATA(data, RANGE_CAPTURED_BT_KEY);
250     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bt), FALSE);
251     bt = OBJECT_GET_DATA(data, RANGE_DISPLAYED_BT_KEY);
252     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bt), TRUE);
253     
254     range_update_dynamics(data);
255   }
256 }
257
258 static void
259 toggle_select_all(GtkWidget *widget, gpointer data)
260 {
261   packet_range_t *range;
262
263
264   range = OBJECT_GET_DATA(data, RANGE_VALUES_KEY);
265   
266   /* is the button now active? */
267   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (widget))) {
268     range->process = range_process_all;
269     range_update_dynamics(data);
270   }
271 }
272
273 static void
274 toggle_select_selected(GtkWidget *widget, gpointer data)
275 {
276   packet_range_t *range;
277
278
279   range = OBJECT_GET_DATA(data, RANGE_VALUES_KEY);
280   
281   /* is the button now active? */
282   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (widget))) {
283     range->process = range_process_selected;
284     range_update_dynamics(data);
285   }
286 }
287
288 static void
289 toggle_select_marked_only(GtkWidget *widget, gpointer data)
290 {
291   packet_range_t *range;
292
293
294   range = OBJECT_GET_DATA(data, RANGE_VALUES_KEY);
295   
296   /* is the button now active? */
297   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (widget))) {
298     range->process = range_process_marked;
299     range_update_dynamics(data);
300   }
301 }
302
303 static void
304 toggle_select_marked_range(GtkWidget *widget, gpointer data)
305 {
306   packet_range_t *range;
307
308
309   range = OBJECT_GET_DATA(data, RANGE_VALUES_KEY);
310   
311   /* is the button now active? */
312   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (widget))) {
313     range->process = range_process_marked_range;
314     range_update_dynamics(data);
315   }
316 }
317
318 static void
319 toggle_select_user_range(GtkWidget *widget, gpointer data)
320 {
321   packet_range_t *range;
322
323
324   range = OBJECT_GET_DATA(data, RANGE_VALUES_KEY);
325   
326   /* is the button now active? */
327   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (widget))) {
328     range->process = range_process_user_range;
329     range_update_dynamics(data);
330   }
331         
332   /* Make the entry widget sensitive or insensitive */
333   gtk_widget_set_sensitive(OBJECT_GET_DATA(data, RANGE_SELECT_USER_ENTRY_KEY), range->process == range_process_user_range);
334
335   /* When selecting user specified range, then focus on the entry */
336   if (range->process == range_process_user_range)
337       gtk_widget_grab_focus(OBJECT_GET_DATA(data, RANGE_SELECT_USER_ENTRY_KEY));
338
339 }
340
341
342 static void
343 range_entry(GtkWidget *widget _U_, gpointer data)
344 {
345   const gchar   *entry_text;
346   GtkWidget     *entry;
347   packet_range_t *range;
348
349
350   range = OBJECT_GET_DATA(data, RANGE_VALUES_KEY);  
351   entry = OBJECT_GET_DATA(data, RANGE_SELECT_USER_ENTRY_KEY);
352
353   gtk_toggle_button_set_active(OBJECT_GET_DATA(data, RANGE_SELECT_USER_KEY), TRUE);
354   entry_text = gtk_entry_get_text (GTK_ENTRY (entry));
355   packet_range_convert_str(range, entry_text);
356   range_update_dynamics(data);
357 }
358
359
360 static void
361 range_entry_in_event(GtkWidget *widget _U_, GdkEventFocus *event _U_, gpointer user_data _U_)
362 {
363     /* This event is called, if the "enter" key is pressed while the key focus (right name?) */
364     /* is in the range entry field. */
365
366     /* Calling range_entry() isn't necessary as all changes are already done while the */
367     /* entry was edited. Calling it here will cause a NULL pointer exception, */
368     /* so don't do: <range_entry(widget, user_data); as we did before. */
369
370     /* What we could do here is to cause the "hosting" dialog box do whatever it */
371     /* needs to do when the default button was pressed. This is difficult as we currently */
372     /* don't have a concept to call the hosting dialog this way. */
373
374     /* XXX - As we might want to put the whole range thing in it's own dialog, this would be */
375     /* a much easier task than it would be today as we could simply close our own dialog. */
376 }
377
378
379 /* create a new range "widget" */
380 GtkWidget *range_new(packet_range_t *range
381 #if GTK_MAJOR_VERSION < 2
382 , GtkAccelGroup *accel_group
383 #endif
384 ) {
385   GtkWidget     *range_tb;
386   GtkWidget     *captured_bt;
387   GtkWidget     *displayed_bt;
388
389   GtkWidget     *select_all_rb;
390   GtkWidget     *select_all_c_lb;
391   GtkWidget     *select_all_d_lb;
392   GtkWidget     *select_curr_rb;
393   GtkWidget     *select_curr_c_lb;
394   GtkWidget     *select_curr_d_lb;
395   GtkWidget     *select_marked_only_rb;
396   GtkWidget     *select_marked_only_c_lb;
397   GtkWidget     *select_marked_only_d_lb;
398   GtkWidget     *select_marked_range_rb;
399   GtkWidget     *select_marked_range_c_lb;
400   GtkWidget     *select_marked_range_d_lb;
401   GtkWidget     *select_user_range_rb;
402   GtkWidget     *select_user_range_c_lb;
403   GtkWidget     *select_user_range_d_lb;
404   GtkWidget     *select_user_range_entry;
405  
406   GtkTooltips   *tooltips;
407
408
409   /* Enable tooltips */
410   tooltips = gtk_tooltips_new();
411
412   /* range table */
413   range_tb = gtk_table_new(7, 3, FALSE);
414   gtk_container_border_width(GTK_CONTAINER(range_tb), 5);
415
416   /* captured button */
417   captured_bt = TOGGLE_BUTTON_NEW_WITH_MNEMONIC("_Captured", accel_group);
418   gtk_table_attach_defaults(GTK_TABLE(range_tb), captured_bt, 1, 2, 0, 1);
419   SIGNAL_CONNECT(captured_bt, "toggled", toggle_captured_cb, range_tb);
420   gtk_tooltips_set_tip (tooltips,captured_bt,("Process all the below chosen packets"), NULL);
421
422   /* displayed button */
423   displayed_bt = TOGGLE_BUTTON_NEW_WITH_MNEMONIC("_Displayed", accel_group);
424   gtk_table_attach_defaults(GTK_TABLE(range_tb), displayed_bt, 2, 3, 0, 1);
425   SIGNAL_CONNECT(displayed_bt, "toggled", toggle_filtered_cb, range_tb);
426   gtk_tooltips_set_tip (tooltips,displayed_bt,("Process only the below chosen packets, which also passes the current display filter"), NULL);
427
428
429   /* Process all packets */
430   select_all_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(NULL, "_All packets", accel_group);
431   gtk_table_attach_defaults(GTK_TABLE(range_tb), select_all_rb, 0, 1, 1, 2);
432   gtk_tooltips_set_tip (tooltips, select_all_rb, 
433       ("Process all packets"), NULL);
434   SIGNAL_CONNECT(select_all_rb, "toggled", toggle_select_all, range_tb);
435
436   select_all_c_lb = gtk_label_new("?");
437   gtk_table_attach_defaults(GTK_TABLE(range_tb), select_all_c_lb, 1, 2, 1, 2);
438   select_all_d_lb = gtk_label_new("?");
439   gtk_table_attach_defaults(GTK_TABLE(range_tb), select_all_d_lb, 2, 3, 1, 2);
440
441
442   /* Process currently selected */
443   select_curr_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(select_all_rb, "_Selected packet only", accel_group);
444   gtk_table_attach_defaults(GTK_TABLE(range_tb), select_curr_rb, 0, 1, 2, 3);
445   gtk_tooltips_set_tip (tooltips, select_curr_rb, ("Process the currently selected packet only"), NULL);
446   SIGNAL_CONNECT(select_curr_rb, "toggled", toggle_select_selected, range_tb);
447
448   select_curr_c_lb = gtk_label_new("?");
449   gtk_table_attach_defaults(GTK_TABLE(range_tb), select_curr_c_lb, 1, 2, 2, 3);
450   select_curr_d_lb = gtk_label_new("?");
451   gtk_table_attach_defaults(GTK_TABLE(range_tb), select_curr_d_lb, 2, 3, 2, 3);
452
453
454   /* Process marked packets */
455   select_marked_only_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(select_all_rb, "_Marked packets only", accel_group);
456   gtk_table_attach_defaults(GTK_TABLE(range_tb), select_marked_only_rb, 0, 1, 3, 4);
457   gtk_tooltips_set_tip (tooltips, select_marked_only_rb, ("Process marked packets only"), NULL);
458   SIGNAL_CONNECT(select_marked_only_rb, "toggled", toggle_select_marked_only, range_tb);
459
460   select_marked_only_c_lb = gtk_label_new("?");
461   gtk_table_attach_defaults(GTK_TABLE(range_tb), select_marked_only_c_lb, 1, 2, 3, 4);
462   select_marked_only_d_lb = gtk_label_new("?");
463   gtk_table_attach_defaults(GTK_TABLE(range_tb), select_marked_only_d_lb, 2, 3, 3, 4);
464
465
466   /* Process packet range between first and last packet */
467   select_marked_range_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(select_all_rb, "From first _to last marked packet", accel_group);
468   gtk_table_attach_defaults(GTK_TABLE(range_tb), select_marked_range_rb, 0, 1, 4, 5);
469   gtk_tooltips_set_tip (tooltips,select_marked_range_rb,("Process all packets between the first and last marker"), NULL);
470   SIGNAL_CONNECT(select_marked_range_rb, "toggled", toggle_select_marked_range, range_tb);
471
472   select_marked_range_c_lb = gtk_label_new("?");
473   gtk_table_attach_defaults(GTK_TABLE(range_tb), select_marked_range_c_lb, 1, 2, 4, 5);
474   select_marked_range_d_lb = gtk_label_new("?");
475   gtk_table_attach_defaults(GTK_TABLE(range_tb), select_marked_range_d_lb, 2, 3, 4, 5);
476
477
478   /* Process a user specified provided packet range : -10,30,40-70,80- */
479   select_user_range_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(select_all_rb, "Specify a packet _range:", accel_group);
480   gtk_table_attach_defaults(GTK_TABLE(range_tb), select_user_range_rb, 0, 1, 5, 6);
481   gtk_tooltips_set_tip (tooltips,select_user_range_rb,("Process a specified packet range"), NULL);
482   SIGNAL_CONNECT(select_user_range_rb, "toggled", toggle_select_user_range, range_tb);
483
484   select_user_range_c_lb = gtk_label_new("?");
485   gtk_table_attach_defaults(GTK_TABLE(range_tb), select_user_range_c_lb, 1, 2, 5, 6);
486   select_user_range_d_lb = gtk_label_new("?");
487   gtk_table_attach_defaults(GTK_TABLE(range_tb), select_user_range_d_lb, 2, 3, 5, 6);
488
489
490   /* The entry part */
491   select_user_range_entry = gtk_entry_new();
492   gtk_entry_set_max_length (GTK_ENTRY (select_user_range_entry), 254);
493   gtk_table_attach_defaults(GTK_TABLE(range_tb), select_user_range_entry, 0, 1, 6, 7);
494   gtk_tooltips_set_tip (tooltips,select_user_range_entry, 
495         ("Specify a range of packet numbers :     \nExample :  1-10,18,25-100,332-"), NULL);
496   SIGNAL_CONNECT(select_user_range_entry,"changed", range_entry, range_tb);
497   SIGNAL_CONNECT(select_user_range_entry,"activate", range_entry_in_event, range_tb);
498
499
500   gtk_widget_show_all(range_tb);
501
502
503   OBJECT_SET_DATA(range_tb, RANGE_VALUES_KEY,               range);
504   OBJECT_SET_DATA(range_tb, RANGE_CAPTURED_BT_KEY,          captured_bt);
505   OBJECT_SET_DATA(range_tb, RANGE_DISPLAYED_BT_KEY,         displayed_bt);
506
507   OBJECT_SET_DATA(range_tb, RANGE_SELECT_ALL_KEY,           select_all_rb);
508   OBJECT_SET_DATA(range_tb, RANGE_SELECT_ALL_C_KEY,         select_all_c_lb);
509   OBJECT_SET_DATA(range_tb, RANGE_SELECT_ALL_D_KEY,         select_all_d_lb);
510
511   OBJECT_SET_DATA(range_tb, RANGE_SELECT_CURR_KEY,          select_curr_rb);
512   OBJECT_SET_DATA(range_tb, RANGE_SELECT_CURR_C_KEY,        select_curr_c_lb);
513   OBJECT_SET_DATA(range_tb, RANGE_SELECT_CURR_D_KEY,        select_curr_d_lb);
514   OBJECT_SET_DATA(range_tb, RANGE_SELECT_CURR_D_KEY,        select_curr_d_lb);
515   OBJECT_SET_DATA(range_tb, RANGE_SELECT_MARKED_KEY,        select_marked_only_rb);
516   OBJECT_SET_DATA(range_tb, RANGE_SELECT_MARKED_C_KEY,      select_marked_only_c_lb);
517   OBJECT_SET_DATA(range_tb, RANGE_SELECT_MARKED_D_KEY,      select_marked_only_d_lb);
518   OBJECT_SET_DATA(range_tb, RANGE_SELECT_MARKED_RANGE_KEY,  select_marked_range_rb);
519   OBJECT_SET_DATA(range_tb, RANGE_SELECT_MARKED_RANGE_C_KEY,select_marked_range_c_lb);
520   OBJECT_SET_DATA(range_tb, RANGE_SELECT_MARKED_RANGE_D_KEY,select_marked_range_d_lb);
521   OBJECT_SET_DATA(range_tb, RANGE_SELECT_USER_KEY,          select_user_range_rb);
522   OBJECT_SET_DATA(range_tb, RANGE_SELECT_USER_C_KEY,        select_user_range_c_lb);
523   OBJECT_SET_DATA(range_tb, RANGE_SELECT_USER_D_KEY,        select_user_range_d_lb);
524   OBJECT_SET_DATA(range_tb, RANGE_SELECT_USER_ENTRY_KEY,    select_user_range_entry);
525
526   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(captured_bt), !range->process_filtered);
527   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(displayed_bt), range->process_filtered);
528
529   switch(range->process) {
530   case(range_process_all):
531     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(select_all_rb),  TRUE);
532     break;
533   case(range_process_selected):
534     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(select_curr_rb),  TRUE);
535     break;
536   case(range_process_marked):
537     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(select_marked_only_rb),  TRUE);
538     break;
539   case(range_process_marked_range):
540     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(select_marked_range_rb),  TRUE);
541     break;
542   case(range_process_user_range):
543     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(select_user_range_rb),  TRUE);
544     break;
545   default:
546     g_assert_not_reached();
547   }
548
549   return range_tb;
550 }