9062a26dd65ddb1050d8179bee63df7e9e513abf
[obnox/wireshark/wip.git] / gtk / goto_dlg.c
1 /* goto_dlg.c
2  * Routines for "go to frame" window
3  *
4  * $Id: goto_dlg.c,v 1.6 2000/05/02 08:04:31 guy Exp $
5  *
6  * Ethereal - Network traffic analyzer
7  * By Gerald Combs <gerald@zing.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * 
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.
15  * 
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.
20  * 
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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <gtk/gtk.h>
32
33 #include <stdlib.h>
34
35 #ifdef HAVE_UNISTD_H
36 #include <unistd.h>
37 #endif
38
39 #ifndef __G_LIB_H__
40 #include <glib.h>
41 #endif
42
43 #include "proto.h"
44 #include "dfilter.h"
45 #include "globals.h"
46
47 #include "goto_dlg.h"
48 #include "prefs_dlg.h"
49 #include "simple_dialog.h"
50 #include "dlg_utils.h"
51
52 /* Capture callback data keys */
53 #define E_GOTO_FNUMBER_KEY     "goto_fnumber_te"
54
55 static void
56 goto_frame_ok_cb(GtkWidget *ok_bt, gpointer parent_w);
57
58 static void
59 goto_frame_close_cb(GtkWidget *close_bt, gpointer parent_w);
60
61 void
62 goto_frame_cb(GtkWidget *w, gpointer d)
63 {
64   GtkWidget     *goto_frame_w, *main_vb, *fnumber_hb, *fnumber_lb, *fnumber_te,
65                 *bbox, *ok_bt, *cancel_bt;
66
67   goto_frame_w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
68   gtk_window_set_title(GTK_WINDOW(goto_frame_w), "Ethereal: Go To Frame");
69   
70   /* Container for each row of widgets */
71   main_vb = gtk_vbox_new(FALSE, 3);
72   gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
73   gtk_container_add(GTK_CONTAINER(goto_frame_w), main_vb);
74   gtk_widget_show(main_vb);
75   
76   /* Frame number row */
77   fnumber_hb = gtk_hbox_new(FALSE, 3);
78   gtk_container_add(GTK_CONTAINER(main_vb), fnumber_hb);
79   gtk_widget_show(fnumber_hb);
80   
81   fnumber_lb = gtk_label_new("Frame number:");
82   gtk_box_pack_start(GTK_BOX(fnumber_hb), fnumber_lb, FALSE, FALSE, 0);
83   gtk_widget_show(fnumber_lb);
84   
85   fnumber_te = gtk_entry_new();
86   gtk_box_pack_start(GTK_BOX(fnumber_hb), fnumber_te, FALSE, FALSE, 0);
87   gtk_widget_show(fnumber_te);
88
89   /* Button row: OK and cancel buttons */
90   bbox = gtk_hbutton_box_new();
91   gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
92   gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
93   gtk_container_add(GTK_CONTAINER(main_vb), bbox);
94   gtk_widget_show(bbox);
95
96   ok_bt = gtk_button_new_with_label ("OK");
97   gtk_signal_connect(GTK_OBJECT(ok_bt), "clicked",
98     GTK_SIGNAL_FUNC(goto_frame_ok_cb), GTK_OBJECT(goto_frame_w));
99   GTK_WIDGET_SET_FLAGS(ok_bt, GTK_CAN_DEFAULT);
100   gtk_box_pack_start (GTK_BOX (bbox), ok_bt, TRUE, TRUE, 0);
101   gtk_widget_grab_default(ok_bt);
102   gtk_widget_show(ok_bt);
103
104   cancel_bt = gtk_button_new_with_label ("Cancel");
105   gtk_signal_connect(GTK_OBJECT(cancel_bt), "clicked",
106     GTK_SIGNAL_FUNC(goto_frame_close_cb), GTK_OBJECT(goto_frame_w));
107   GTK_WIDGET_SET_FLAGS(cancel_bt, GTK_CAN_DEFAULT);
108   gtk_box_pack_start (GTK_BOX (bbox), cancel_bt, TRUE, TRUE, 0);
109   gtk_widget_show(cancel_bt);
110
111   /* Attach pointers to needed widgets to the capture prefs window/object */
112   gtk_object_set_data(GTK_OBJECT(goto_frame_w), E_GOTO_FNUMBER_KEY, fnumber_te);
113
114   /* Catch the "activate" signal on the frame number text entry, so that
115      if the user types Return there, we act as if the "OK" button
116      had been selected, as happens if Return is typed if some widget
117      that *doesn't* handle the Return key has the input focus. */
118   dlg_set_activate(fnumber_te, ok_bt);
119
120   /* Catch the "key_press_event" signal in the window, so that we can catch
121      the ESC key being pressed and act as if the "Cancel" button had
122      been selected. */
123   dlg_set_cancel(goto_frame_w, cancel_bt);
124
125   /* Give the initial focus to the "Frame number" entry box. */
126   gtk_widget_grab_focus(fnumber_te);
127
128   gtk_widget_show(goto_frame_w);
129 }
130
131 static void
132 goto_frame_ok_cb(GtkWidget *ok_bt, gpointer parent_w)
133 {
134   GtkWidget *fnumber_te;
135   gchar *fnumber_text;
136   guint fnumber;
137   char *p;
138
139   fnumber_te = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_GOTO_FNUMBER_KEY);
140
141   fnumber_text = gtk_entry_get_text(GTK_ENTRY(fnumber_te));
142   fnumber = strtoul(fnumber_text, &p, 10);
143   if (p == fnumber_text || *p != '\0') {
144     /* Illegal number.
145        XXX - what about negative numbers (which "strtoul()" allows)?
146        Can we hack up signal handlers for the widget to make it
147        reject attempts to type in characters other than digits? */
148     simple_dialog(ESD_TYPE_WARN, NULL,
149                 "The frame number you entered isn't a valid number.");
150     return;
151   }
152
153   switch (goto_frame(&cf, fnumber)) {
154
155   case NO_SUCH_FRAME:
156     simple_dialog(ESD_TYPE_WARN, NULL, "There is no frame with that frame number.");
157     return;
158
159   case FRAME_NOT_DISPLAYED:
160     /* XXX - add it to the display filter? */
161     simple_dialog(ESD_TYPE_WARN, NULL, "The frame with that frame number is not currently being displayed.");
162     return;
163
164   case FOUND_FRAME:
165     gtk_widget_destroy(GTK_WIDGET(parent_w));
166     break;
167   }
168 }
169
170 static void
171 goto_frame_close_cb(GtkWidget *close_bt, gpointer parent_w)
172 {
173   gtk_grab_remove(GTK_WIDGET(parent_w));
174   gtk_widget_destroy(GTK_WIDGET(parent_w));
175 }