Fix more tooltips fixes.
[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 #include "../simple_dialog.h"
35 #include "../packet-range.h"
36
37 #include "gtk/gui_utils.h"
38 #include "gtk/dlg_utils.h"
39 #include "gtk/range_utils.h"
40
41
42 #define RANGE_VALUES_KEY                "range_values"
43 #define RANGE_CAPTURED_BT_KEY           "range_captured_button"
44 #define RANGE_DISPLAYED_BT_KEY          "range_displayed_button"
45
46 #define RANGE_SELECT_ALL_KEY            "range_select_all_rb"
47 #define RANGE_SELECT_ALL_C_KEY          "range_select_all_c_lb"
48 #define RANGE_SELECT_ALL_D_KEY          "range_select_all_d_lb"
49 #define RANGE_SELECT_CURR_KEY           "range_select_curr_rb"
50 #define RANGE_SELECT_CURR_C_KEY         "range_select_curr_c_lb"
51 #define RANGE_SELECT_CURR_D_KEY         "range_select_curr_d_lb"
52 #define RANGE_SELECT_MARKED_KEY         "range_select_marked_only_rb"
53 #define RANGE_SELECT_MARKED_C_KEY       "range_select_marked_only_c_lb"
54 #define RANGE_SELECT_MARKED_D_KEY       "range_select_marked_only_d_lb"
55 #define RANGE_SELECT_MARKED_RANGE_KEY   "range_select_marked_range_rb"
56 #define RANGE_SELECT_MARKED_RANGE_C_KEY "range_select_marked_range_c_lb"
57 #define RANGE_SELECT_MARKED_RANGE_D_KEY "range_select_marked_range_d_lb"
58 #define RANGE_SELECT_USER_KEY           "range_select_user_range_rb"
59 #define RANGE_SELECT_USER_C_KEY         "range_select_user_range_c_lb"
60 #define RANGE_SELECT_USER_D_KEY         "range_select_user_range_d_lb"
61 #define RANGE_SELECT_USER_ENTRY_KEY     "range_select_user_range_entry"
62
63 #define RANGE_REMOVE_IGNORED_KEY        "range_remove_ignored"
64 #define RANGE_IGNORED_C_KEY             "range_ignored_c_lb"
65 #define RANGE_IGNORED_D_KEY             "range_ignored_d_lb"
66
67 gboolean
68 range_check_validity(packet_range_t *range)
69 {
70   switch (packet_range_check(range)) {
71
72   case CVT_NO_ERROR:
73     return TRUE;
74
75   case CVT_SYNTAX_ERROR:
76     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
77       "The specified range of packets isn't a valid range.");
78     return FALSE;
79
80   case CVT_NUMBER_TOO_BIG:
81     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
82       "The specified range of packets has a packet number that's too large.");
83     return FALSE;
84
85   default:
86     g_assert_not_reached();
87     return FALSE;
88   }
89 }
90
91 /* update all "dynamic" things */
92 void
93 range_update_dynamics(gpointer data)
94 {
95   packet_range_t *range;
96   GtkWidget     *range_displayed_bt;
97   gboolean      filtered_active;
98   gint          selected_num;
99   gboolean      can_select;
100   gboolean      selected_packets;
101   gchar         label_text[100];
102   guint32       ignored_cnt = 0, displayed_ignored_cnt = 0;
103
104   range = g_object_get_data(G_OBJECT(data), RANGE_VALUES_KEY);
105   
106   range_displayed_bt = g_object_get_data(G_OBJECT(data), RANGE_DISPLAYED_BT_KEY);
107   filtered_active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(range_displayed_bt));
108
109   /* Enable saving only the displayed packets only if there *are*
110      displayed packets. */
111   if (range->displayed_cnt != 0)
112     gtk_widget_set_sensitive(range_displayed_bt, TRUE);
113   else {
114     /* If saving the displayed packets is selected, select saving the
115        captured packets. */
116     filtered_active = FALSE;
117     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(G_OBJECT(data), RANGE_SELECT_ALL_KEY)), FALSE);
118     gtk_widget_set_sensitive(range_displayed_bt, FALSE);
119   }
120
121   gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data), RANGE_SELECT_ALL_C_KEY), !filtered_active);
122   if (range->remove_ignored) {
123     g_snprintf(label_text, sizeof(label_text), "%u", cfile.count - range->ignored_cnt);
124   } else {
125     g_snprintf(label_text, sizeof(label_text), "%u", cfile.count);
126   }
127   gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(data), RANGE_SELECT_ALL_C_KEY)), label_text);
128   gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data), RANGE_SELECT_ALL_D_KEY), filtered_active);
129   if (range->remove_ignored) {
130     g_snprintf(label_text, sizeof(label_text), "%u", range->displayed_cnt - range->displayed_ignored_cnt);
131   } else {
132     g_snprintf(label_text, sizeof(label_text), "%u", range->displayed_cnt);
133   }
134   gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(data), RANGE_SELECT_ALL_D_KEY)), label_text);
135
136   /* Enable saving the currently-selected packet only if there *is* a
137      currently-selected packet. */
138   selected_num = (cfile.current_frame) ? cfile.current_frame->num : 0;
139   can_select = (selected_num != 0);
140   if (can_select) {
141     gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data), RANGE_SELECT_CURR_KEY), TRUE);
142     gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data), RANGE_SELECT_CURR_C_KEY), !filtered_active);
143     gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data), RANGE_SELECT_CURR_D_KEY), filtered_active);
144   } else {
145     /* If "save selected packet" is selected, select "save all packets". */
146     if (range->process == range_process_selected) {
147       range->process = range_process_all;
148       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(G_OBJECT(data), RANGE_SELECT_ALL_KEY)), TRUE);
149     }
150     gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data), RANGE_SELECT_CURR_KEY), FALSE);
151     gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data), RANGE_SELECT_CURR_C_KEY), FALSE);
152     gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data), RANGE_SELECT_CURR_D_KEY), FALSE);
153   }
154   /* XXX: how to update the radio button label but keep the mnemonic? */
155 /*g_snprintf(label_text, sizeof(label_text), "_Selected packet #%u only", selected_num);
156   gtk_label_set_text(GTK_LABEL(GTK_BIN(select_curr_rb)->child), label_text);*/
157   if (range->remove_ignored && can_select && cfile.current_frame->flags.ignored) {
158     g_snprintf(label_text, sizeof(label_text), "0");
159   } else {
160     g_snprintf(label_text, sizeof(label_text), "%u", selected_num ? 1 : 0);
161   }
162   gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(data), RANGE_SELECT_CURR_C_KEY)), label_text);
163   if (range->remove_ignored && can_select && cfile.current_frame->flags.ignored) {
164     g_snprintf(label_text, sizeof(label_text), "0");
165   } else {
166     g_snprintf(label_text, sizeof(label_text), "%u", selected_num ? 1 : 0);
167   }
168   gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(data), RANGE_SELECT_CURR_D_KEY)), label_text);
169
170   /* Enable the buttons for saving marked packets only if there *are*
171      marked packets. */
172   if (filtered_active)
173     selected_packets = (range->displayed_marked_cnt != 0);
174   else
175     selected_packets = (cfile.marked_count > 0);
176   if (selected_packets) {
177     gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data), RANGE_SELECT_MARKED_KEY), TRUE);
178     gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data), RANGE_SELECT_MARKED_C_KEY), !filtered_active);
179     gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data), RANGE_SELECT_MARKED_D_KEY), filtered_active);
180   }
181   else {
182     /* If "save marked packet" is selected, select "save all packets". */
183     if (range->process == range_process_marked) {
184       range->process = range_process_all;
185       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(G_OBJECT(data), RANGE_SELECT_ALL_KEY)), TRUE);
186     }
187     gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data), RANGE_SELECT_MARKED_KEY), FALSE);
188     gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data), RANGE_SELECT_MARKED_C_KEY), FALSE);
189     gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data), RANGE_SELECT_MARKED_D_KEY), FALSE);
190   }
191   if (range->remove_ignored) {
192     g_snprintf(label_text, sizeof(label_text), "%u", cfile.marked_count - range->ignored_marked_cnt);
193   } else {
194     g_snprintf(label_text, sizeof(label_text), "%u", cfile.marked_count);
195   }
196   gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(data), RANGE_SELECT_MARKED_C_KEY)), label_text);
197   if (range->remove_ignored) {
198     g_snprintf(label_text, sizeof(label_text), "%u", range->displayed_marked_cnt - range->displayed_ignored_marked_cnt);
199   } else {
200     g_snprintf(label_text, sizeof(label_text), "%u", range->displayed_marked_cnt);
201   }
202   gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(data), RANGE_SELECT_MARKED_D_KEY)), label_text);
203
204   /* Enable the buttons for saving the range of marked packets only if
205      there *is* a range of marked packets. */
206   if (filtered_active)
207     selected_packets = (range->displayed_mark_range_cnt != 0);
208   else
209     selected_packets = (range->mark_range_cnt != 0);
210   if (selected_packets) {
211     gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data), RANGE_SELECT_MARKED_RANGE_KEY), TRUE);
212     gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data), RANGE_SELECT_MARKED_RANGE_C_KEY), !filtered_active);
213     gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data), RANGE_SELECT_MARKED_RANGE_D_KEY), filtered_active);
214   }
215   else {
216     /* If "save range between first and last marked packet" is selected,
217        select "save all packets". */
218     if (range->process == range_process_marked_range) {
219       range->process = range_process_all;
220       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g_object_get_data(G_OBJECT(data), RANGE_SELECT_ALL_KEY)), TRUE);
221     }
222     gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data), RANGE_SELECT_MARKED_RANGE_KEY), FALSE);
223     gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data), RANGE_SELECT_MARKED_RANGE_C_KEY), FALSE);
224     gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data), RANGE_SELECT_MARKED_RANGE_D_KEY), FALSE);
225   }
226   if (range->remove_ignored) {
227     g_snprintf(label_text, sizeof(label_text), "%u", range->mark_range_cnt - range->ignored_mark_range_cnt);
228   } else {
229     g_snprintf(label_text, sizeof(label_text), "%u", range->mark_range_cnt);
230   }
231   gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(data), RANGE_SELECT_MARKED_RANGE_C_KEY)), label_text);
232   if (range->remove_ignored) {
233     g_snprintf(label_text, sizeof(label_text), "%u", range->displayed_mark_range_cnt - range->displayed_ignored_mark_range_cnt);
234   } else {
235     g_snprintf(label_text, sizeof(label_text), "%u", range->displayed_mark_range_cnt);
236   }
237   gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(data), RANGE_SELECT_MARKED_RANGE_D_KEY)), label_text);
238
239   gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data), RANGE_SELECT_USER_KEY), TRUE);
240   gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data), RANGE_SELECT_USER_C_KEY), !filtered_active);
241   gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data), RANGE_SELECT_USER_D_KEY), filtered_active);
242   if (range->remove_ignored) {
243     g_snprintf(label_text, sizeof(label_text), "%u", range->user_range_cnt - range->ignored_user_range_cnt);
244   } else {
245     g_snprintf(label_text, sizeof(label_text), "%u", range->user_range_cnt);
246   }
247   gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(data), RANGE_SELECT_USER_C_KEY)), label_text);
248   if (range->remove_ignored) {
249     g_snprintf(label_text, sizeof(label_text), "%u", range->displayed_user_range_cnt - range->displayed_ignored_user_range_cnt);
250   } else {
251     g_snprintf(label_text, sizeof(label_text), "%u", range->displayed_user_range_cnt);
252   }
253   gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(data), RANGE_SELECT_USER_D_KEY)), label_text);
254
255   switch(range->process) {
256   case(range_process_all):
257     ignored_cnt = range->ignored_cnt;
258     displayed_ignored_cnt = range->displayed_ignored_cnt;
259     break;
260   case(range_process_selected):
261     ignored_cnt = (can_select && cfile.current_frame->flags.ignored) ? 1 : 0;
262     displayed_ignored_cnt = ignored_cnt;
263     break;
264   case(range_process_marked):
265     ignored_cnt = range->ignored_marked_cnt;
266     displayed_ignored_cnt = range->displayed_ignored_marked_cnt;
267     break;
268   case(range_process_marked_range):
269     ignored_cnt = range->ignored_mark_range_cnt;
270     displayed_ignored_cnt = range->displayed_ignored_mark_range_cnt;
271     break;
272   case(range_process_user_range):
273     ignored_cnt = range->ignored_user_range_cnt;
274     displayed_ignored_cnt = range->displayed_ignored_user_range_cnt;
275     break;
276   default:
277     g_assert_not_reached();
278   }
279
280   if (filtered_active)
281     selected_packets = (displayed_ignored_cnt != 0);
282   else
283     selected_packets = (ignored_cnt != 0);
284
285   if (selected_packets) {
286     gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data), RANGE_REMOVE_IGNORED_KEY), TRUE);
287     gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data), RANGE_IGNORED_C_KEY), !filtered_active);
288     gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data), RANGE_IGNORED_D_KEY), filtered_active);
289   } else {
290     gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data), RANGE_REMOVE_IGNORED_KEY), FALSE);
291     gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data), RANGE_IGNORED_C_KEY), FALSE);
292     gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data), RANGE_IGNORED_D_KEY), FALSE);
293   }
294
295   g_snprintf(label_text, sizeof(label_text), "%u", ignored_cnt);
296   gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(data), RANGE_IGNORED_C_KEY)), label_text);  g_snprintf(label_text, sizeof(label_text), "%u", displayed_ignored_cnt);
297   gtk_label_set_text(GTK_LABEL(g_object_get_data(G_OBJECT(data), RANGE_IGNORED_D_KEY)), label_text);
298 }
299
300
301 static void
302 toggle_captured_cb(GtkWidget *widget, gpointer data)
303 {
304   GtkWidget *bt;
305   packet_range_t *range;
306
307
308   range = g_object_get_data(G_OBJECT(data), RANGE_VALUES_KEY);
309
310   /* is the button now active? */
311   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (widget))) {
312     /* They changed the state of the "captured" button. */
313     range->process_filtered = FALSE;
314
315     bt = g_object_get_data(G_OBJECT(data), RANGE_CAPTURED_BT_KEY);
316     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bt), TRUE);
317     bt = g_object_get_data(G_OBJECT(data), RANGE_DISPLAYED_BT_KEY);
318     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bt), FALSE);
319
320     range_update_dynamics(data);
321   }
322 }
323
324 static void
325 toggle_filtered_cb(GtkWidget *widget, gpointer data)
326 {
327   GtkWidget *bt;
328   packet_range_t *range;
329
330
331   range = g_object_get_data(G_OBJECT(data), RANGE_VALUES_KEY);
332   
333   /* is the button now active? */
334   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (widget))) {
335     range->process_filtered = TRUE;
336     bt = g_object_get_data(G_OBJECT(data), RANGE_CAPTURED_BT_KEY);
337     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bt), FALSE);
338     bt = g_object_get_data(G_OBJECT(data), RANGE_DISPLAYED_BT_KEY);
339     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bt), TRUE);
340     
341     range_update_dynamics(data);
342   }
343 }
344
345 static void
346 toggle_select_all(GtkWidget *widget, gpointer data)
347 {
348   packet_range_t *range;
349
350
351   range = g_object_get_data(G_OBJECT(data), RANGE_VALUES_KEY);
352   
353   /* is the button now active? */
354   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (widget))) {
355     range->process = range_process_all;
356     range_update_dynamics(data);
357   }
358 }
359
360 static void
361 toggle_select_selected(GtkWidget *widget, gpointer data)
362 {
363   packet_range_t *range;
364
365
366   range = g_object_get_data(G_OBJECT(data), RANGE_VALUES_KEY);
367   
368   /* is the button now active? */
369   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (widget))) {
370     range->process = range_process_selected;
371     range_update_dynamics(data);
372   }
373 }
374
375 static void
376 toggle_select_marked_only(GtkWidget *widget, gpointer data)
377 {
378   packet_range_t *range;
379
380
381   range = g_object_get_data(G_OBJECT(data), RANGE_VALUES_KEY);
382   
383   /* is the button now active? */
384   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (widget))) {
385     range->process = range_process_marked;
386     range_update_dynamics(data);
387   }
388 }
389
390 static void
391 toggle_select_marked_range(GtkWidget *widget, gpointer data)
392 {
393   packet_range_t *range;
394
395
396   range = g_object_get_data(G_OBJECT(data), RANGE_VALUES_KEY);
397   
398   /* is the button now active? */
399   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (widget))) {
400     range->process = range_process_marked_range;
401     range_update_dynamics(data);
402   }
403 }
404
405 static void
406 toggle_select_user_range(GtkWidget *widget, gpointer data)
407 {
408   packet_range_t *range;
409
410
411   range = g_object_get_data(G_OBJECT(data), RANGE_VALUES_KEY);
412   
413   /* is the button now active? */
414   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (widget))) {
415     range->process = range_process_user_range;
416     range_update_dynamics(data);
417   }
418         
419   /* Make the entry widget sensitive or insensitive */
420   gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(data), RANGE_SELECT_USER_ENTRY_KEY), range->process == range_process_user_range);
421
422   /* When selecting user specified range, then focus on the entry */
423   if (range->process == range_process_user_range)
424     gtk_widget_grab_focus(g_object_get_data(G_OBJECT(data), RANGE_SELECT_USER_ENTRY_KEY));
425
426 }
427
428 static void
429 toggle_remove_ignored(GtkWidget *widget, gpointer data)
430 {
431   packet_range_t *range;
432
433   range = g_object_get_data(G_OBJECT(data), RANGE_VALUES_KEY);
434   
435   /* is the button now active? */
436   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (widget))) {
437     range->remove_ignored = TRUE;
438   } else {
439     range->remove_ignored = FALSE;
440   }
441
442   range_update_dynamics(data);
443 }
444
445 static void
446 range_entry(GtkWidget *widget _U_, gpointer data)
447 {
448   const gchar   *entry_text;
449   GtkWidget     *entry;
450   packet_range_t *range;
451
452
453   range = g_object_get_data(G_OBJECT(data), RANGE_VALUES_KEY);  
454   entry = g_object_get_data(G_OBJECT(data), RANGE_SELECT_USER_ENTRY_KEY);
455
456   gtk_toggle_button_set_active(g_object_get_data(G_OBJECT(data), RANGE_SELECT_USER_KEY), TRUE);
457   entry_text = gtk_entry_get_text (GTK_ENTRY (entry));
458   packet_range_convert_str(range, entry_text);
459   range_update_dynamics(data);
460 }
461
462
463 static void
464 range_entry_in_event(GtkWidget *widget _U_, GdkEventFocus *event _U_, gpointer user_data _U_)
465 {
466     /* This event is called, if the "enter" key is pressed while the key focus (right name?) */
467     /* is in the range entry field. */
468
469     /* Calling range_entry() isn't necessary as all changes are already done while the */
470     /* entry was edited. Calling it here will cause a NULL pointer exception, */
471     /* so don't do: <range_entry(widget, user_data); as we did before. */
472
473     /* What we could do here is to cause the "hosting" dialog box do whatever it */
474     /* needs to do when the default button was pressed. This is difficult as we currently */
475     /* don't have a concept to call the hosting dialog this way. */
476
477     /* XXX - As we might want to put the whole range thing in it's own dialog, this would be */
478     /* a much easier task than it would be today as we could simply close our own dialog. */
479 }
480
481
482 /* create a new range "widget" */
483 GtkWidget *range_new(packet_range_t *range)
484 {
485   GtkWidget     *range_tb;
486   GtkWidget     *captured_bt;
487   GtkWidget     *displayed_bt;
488
489   GtkWidget     *select_all_rb;
490   GtkWidget     *select_all_c_lb;
491   GtkWidget     *select_all_d_lb;
492   GtkWidget     *select_curr_rb;
493   GtkWidget     *select_curr_c_lb;
494   GtkWidget     *select_curr_d_lb;
495   GtkWidget     *select_marked_only_rb;
496   GtkWidget     *select_marked_only_c_lb;
497   GtkWidget     *select_marked_only_d_lb;
498   GtkWidget     *select_marked_range_rb;
499   GtkWidget     *select_marked_range_c_lb;
500   GtkWidget     *select_marked_range_d_lb;
501   GtkWidget     *select_user_range_rb;
502   GtkWidget     *select_user_range_c_lb;
503   GtkWidget     *select_user_range_d_lb;
504   GtkWidget     *select_user_range_entry;
505   GtkWidget     *remove_ignored_cb;
506   GtkWidget     *ignored_c_lb;
507   GtkWidget     *ignored_d_lb;
508  
509   /* range table */
510   range_tb = gtk_table_new(7, 3, FALSE);
511   gtk_container_set_border_width(GTK_CONTAINER(range_tb), 5);
512
513   /* captured button */
514   captured_bt = gtk_toggle_button_new_with_mnemonic("_Captured");
515   gtk_table_attach_defaults(GTK_TABLE(range_tb), captured_bt, 1, 2, 0, 1);
516   g_signal_connect(captured_bt, "toggled", G_CALLBACK(toggle_captured_cb), range_tb);
517   gtk_widget_set_tooltip_text (captured_bt,("Process all the below chosen packets"));
518
519   /* displayed button */
520   displayed_bt = gtk_toggle_button_new_with_mnemonic("_Displayed");
521   gtk_table_attach_defaults(GTK_TABLE(range_tb), displayed_bt, 2, 3, 0, 1);
522   g_signal_connect(displayed_bt, "toggled", G_CALLBACK(toggle_filtered_cb), range_tb);
523   gtk_widget_set_tooltip_text (displayed_bt,("Process only the below chosen packets, which also passes the current display filter"));
524
525
526   /* Process all packets */
527   select_all_rb = gtk_radio_button_new_with_mnemonic_from_widget(NULL, "_All packets");
528   gtk_table_attach_defaults(GTK_TABLE(range_tb), select_all_rb, 0, 1, 1, 2);
529   gtk_widget_set_tooltip_text (select_all_rb, ("Process all packets"));
530   g_signal_connect(select_all_rb, "toggled", G_CALLBACK(toggle_select_all), range_tb);
531
532   select_all_c_lb = gtk_label_new("?");
533   gtk_table_attach_defaults(GTK_TABLE(range_tb), select_all_c_lb, 1, 2, 1, 2);
534   select_all_d_lb = gtk_label_new("?");
535   gtk_table_attach_defaults(GTK_TABLE(range_tb), select_all_d_lb, 2, 3, 1, 2);
536
537
538   /* Process currently selected */
539   select_curr_rb = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(select_all_rb), "_Selected packet only");
540   gtk_table_attach_defaults(GTK_TABLE(range_tb), select_curr_rb, 0, 1, 2, 3);
541   gtk_widget_set_tooltip_text (select_curr_rb, ("Process the currently selected packet only"));
542   g_signal_connect(select_curr_rb, "toggled", G_CALLBACK(toggle_select_selected), range_tb);
543
544   select_curr_c_lb = gtk_label_new("?");
545   gtk_table_attach_defaults(GTK_TABLE(range_tb), select_curr_c_lb, 1, 2, 2, 3);
546   select_curr_d_lb = gtk_label_new("?");
547   gtk_table_attach_defaults(GTK_TABLE(range_tb), select_curr_d_lb, 2, 3, 2, 3);
548
549
550   /* Process marked packets */
551   select_marked_only_rb = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(select_all_rb), "_Marked packets only");
552   gtk_table_attach_defaults(GTK_TABLE(range_tb), select_marked_only_rb, 0, 1, 3, 4);
553   gtk_widget_set_tooltip_text (select_marked_only_rb, ("Process marked packets only"));
554   g_signal_connect(select_marked_only_rb, "toggled", G_CALLBACK(toggle_select_marked_only), range_tb);
555
556   select_marked_only_c_lb = gtk_label_new("?");
557   gtk_table_attach_defaults(GTK_TABLE(range_tb), select_marked_only_c_lb, 1, 2, 3, 4);
558   select_marked_only_d_lb = gtk_label_new("?");
559   gtk_table_attach_defaults(GTK_TABLE(range_tb), select_marked_only_d_lb, 2, 3, 3, 4);
560
561
562   /* Process packet range between first and last packet */
563   select_marked_range_rb = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(select_all_rb), "From first _to last marked packet");
564   gtk_table_attach_defaults(GTK_TABLE(range_tb), select_marked_range_rb, 0, 1, 4, 5);
565   gtk_widget_set_tooltip_text (select_marked_range_rb,("Process all packets between the first and last marker"));
566   g_signal_connect(select_marked_range_rb, "toggled", G_CALLBACK(toggle_select_marked_range), range_tb);
567
568   select_marked_range_c_lb = gtk_label_new("?");
569   gtk_table_attach_defaults(GTK_TABLE(range_tb), select_marked_range_c_lb, 1, 2, 4, 5);
570   select_marked_range_d_lb = gtk_label_new("?");
571   gtk_table_attach_defaults(GTK_TABLE(range_tb), select_marked_range_d_lb, 2, 3, 4, 5);
572
573
574   /* Process a user specified provided packet range : -10,30,40-70,80- */
575   select_user_range_rb = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(select_all_rb), "Specify a packet _range:");
576   gtk_table_attach_defaults(GTK_TABLE(range_tb), select_user_range_rb, 0, 1, 5, 6);
577   gtk_widget_set_tooltip_text (select_user_range_rb,("Process a specified packet range"));
578   g_signal_connect(select_user_range_rb, "toggled", G_CALLBACK(toggle_select_user_range), range_tb);
579
580   select_user_range_c_lb = gtk_label_new("?");
581   gtk_table_attach_defaults(GTK_TABLE(range_tb), select_user_range_c_lb, 1, 2, 5, 6);
582   select_user_range_d_lb = gtk_label_new("?");
583   gtk_table_attach_defaults(GTK_TABLE(range_tb), select_user_range_d_lb, 2, 3, 5, 6);
584
585
586   /* The entry part */
587   select_user_range_entry = gtk_entry_new();
588   gtk_entry_set_max_length (GTK_ENTRY (select_user_range_entry), 254);
589   gtk_table_attach_defaults(GTK_TABLE(range_tb), select_user_range_entry, 0, 1, 6, 7);
590   gtk_widget_set_tooltip_text (select_user_range_entry, ("Specify a range of packet numbers :     \nExample :  1-10,18,25-100,332-"));
591   g_signal_connect(select_user_range_entry,"changed", G_CALLBACK(range_entry), range_tb);
592   g_signal_connect(select_user_range_entry,"activate", G_CALLBACK(range_entry_in_event), range_tb);
593
594   /* Remove ignored packets */
595   remove_ignored_cb = gtk_check_button_new_with_mnemonic("Remove _Ignored packets");
596   gtk_table_attach_defaults(GTK_TABLE(range_tb), remove_ignored_cb, 0, 1, 7, 8);
597   gtk_widget_set_tooltip_text (remove_ignored_cb,("Remove all packets marked as Ignored"));
598   g_signal_connect(remove_ignored_cb, "toggled", G_CALLBACK(toggle_remove_ignored), range_tb);
599
600   ignored_c_lb = gtk_label_new("?");
601   gtk_table_attach_defaults(GTK_TABLE(range_tb), ignored_c_lb, 1, 2, 7, 8);
602   ignored_d_lb = gtk_label_new("?");
603   gtk_table_attach_defaults(GTK_TABLE(range_tb), ignored_d_lb, 2, 3, 7, 8);
604
605   gtk_widget_show_all(range_tb);
606
607
608   g_object_set_data(G_OBJECT(range_tb), RANGE_VALUES_KEY,               range);
609   g_object_set_data(G_OBJECT(range_tb), RANGE_CAPTURED_BT_KEY,          captured_bt);
610   g_object_set_data(G_OBJECT(range_tb), RANGE_DISPLAYED_BT_KEY,         displayed_bt);
611
612   g_object_set_data(G_OBJECT(range_tb), RANGE_SELECT_ALL_KEY,           select_all_rb);
613   g_object_set_data(G_OBJECT(range_tb), RANGE_SELECT_ALL_C_KEY,         select_all_c_lb);
614   g_object_set_data(G_OBJECT(range_tb), RANGE_SELECT_ALL_D_KEY,         select_all_d_lb);
615
616   g_object_set_data(G_OBJECT(range_tb), RANGE_SELECT_CURR_KEY,          select_curr_rb);
617   g_object_set_data(G_OBJECT(range_tb), RANGE_SELECT_CURR_C_KEY,        select_curr_c_lb);
618   g_object_set_data(G_OBJECT(range_tb), RANGE_SELECT_CURR_D_KEY,        select_curr_d_lb);
619   g_object_set_data(G_OBJECT(range_tb), RANGE_SELECT_CURR_D_KEY,        select_curr_d_lb);
620   g_object_set_data(G_OBJECT(range_tb), RANGE_SELECT_MARKED_KEY,        select_marked_only_rb);
621   g_object_set_data(G_OBJECT(range_tb), RANGE_SELECT_MARKED_C_KEY,      select_marked_only_c_lb);
622   g_object_set_data(G_OBJECT(range_tb), RANGE_SELECT_MARKED_D_KEY,      select_marked_only_d_lb);
623   g_object_set_data(G_OBJECT(range_tb), RANGE_SELECT_MARKED_RANGE_KEY,  select_marked_range_rb);
624   g_object_set_data(G_OBJECT(range_tb), RANGE_SELECT_MARKED_RANGE_C_KEY,select_marked_range_c_lb);
625   g_object_set_data(G_OBJECT(range_tb), RANGE_SELECT_MARKED_RANGE_D_KEY,select_marked_range_d_lb);
626   g_object_set_data(G_OBJECT(range_tb), RANGE_SELECT_USER_KEY,          select_user_range_rb);
627   g_object_set_data(G_OBJECT(range_tb), RANGE_SELECT_USER_C_KEY,        select_user_range_c_lb);
628   g_object_set_data(G_OBJECT(range_tb), RANGE_SELECT_USER_D_KEY,        select_user_range_d_lb);
629   g_object_set_data(G_OBJECT(range_tb), RANGE_SELECT_USER_ENTRY_KEY,    select_user_range_entry);
630
631   g_object_set_data(G_OBJECT(range_tb), RANGE_REMOVE_IGNORED_KEY,       remove_ignored_cb);
632   g_object_set_data(G_OBJECT(range_tb), RANGE_IGNORED_C_KEY,            ignored_c_lb);
633   g_object_set_data(G_OBJECT(range_tb), RANGE_IGNORED_D_KEY,            ignored_d_lb);
634
635   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(captured_bt), !range->process_filtered);
636   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(displayed_bt), range->process_filtered);
637
638   switch(range->process) {
639   case(range_process_all):
640     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(select_all_rb),  TRUE);
641     break;
642   case(range_process_selected):
643     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(select_curr_rb),  TRUE);
644     break;
645   case(range_process_marked):
646     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(select_marked_only_rb),  TRUE);
647     break;
648   case(range_process_marked_range):
649     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(select_marked_range_rb),  TRUE);
650     break;
651   case(range_process_user_range):
652     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(select_user_range_rb),  TRUE);
653     break;
654   default:
655     g_assert_not_reached();
656   }
657
658   return range_tb;
659 }