aboutsummaryrefslogtreecommitdiffstats
path: root/gtk/proto_draw.c
diff options
context:
space:
mode:
authorRichard Sharpe <sharpe@ns.aus.com>2003-11-29 06:09:54 +0000
committerRichard Sharpe <sharpe@ns.aus.com>2003-11-29 06:09:54 +0000
commit02087e332f732dab10eceabe2d5ffc32fde5fcb2 (patch)
tree84984243a958447fe63286df1d793aa9cd46bfba /gtk/proto_draw.c
parentc34428926028b6f81f43ac2c3e2c9ddddbfe19ac (diff)
Add an entry in the byte_view pane that allows the user to save the highlighted
data to a file. This allows the user to select some stuff, and analyse it with external tools, and is very useful for quickly prototying dissectors etc. This works by retrieving the info that is needed to define where the selected region is. It puts up a dialog box that asks for the file to save in. However, it is an ugly hack, because it reuses print_file_cb, while print_file_cb should be moved into file_dlg.c. It also needs to have some warning dialogs put up in error cases. Finally, it would be good to be able to select a region in the byte_view, which you can do with click and drag, and then have a menu item to save the selected bytes. svn path=/trunk/; revision=9116
Diffstat (limited to 'gtk/proto_draw.c')
-rw-r--r--gtk/proto_draw.c179
1 files changed, 178 insertions, 1 deletions
diff --git a/gtk/proto_draw.c b/gtk/proto_draw.c
index c80c91c745..0acf96efa1 100644
--- a/gtk/proto_draw.c
+++ b/gtk/proto_draw.c
@@ -1,7 +1,7 @@
/* proto_draw.c
* Routines for GTK+ packet display
*
- * $Id: proto_draw.c,v 1.65 2003/11/25 14:07:45 sahlberg Exp $
+ * $Id: proto_draw.c,v 1.66 2003/11/29 06:09:54 sharpe Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -44,8 +44,11 @@
#include "colors.h"
#include "prefs.h"
+#include "filter_prefs.h"
+#include "file_dlg.h"
#include "proto_draw.h"
#include "packet_win.h"
+#include "dlg_utils.h"
#include "ui_util.h"
#include "gtkglobals.h"
#include "compat_macros.h"
@@ -729,6 +732,179 @@ add_byte_views(epan_dissect_t *edt, GtkWidget *tree_view,
gtk_notebook_set_page(GTK_NOTEBOOK(byte_nb_ptr), 0);
}
+#include <fcntl.h>
+
+static GtkWidget *savehex_dlg=NULL;
+static GtkWidget *file_entry=NULL;
+
+static void
+savehex_dlg_destroy_cb(void)
+{
+ savehex_dlg = NULL;
+}
+
+static void
+savehex_dlg_cancel_cb(GtkWidget *cancel_bt _U_, gpointer parent_w)
+{
+ gtk_widget_destroy(GTK_WIDGET(parent_w));
+}
+
+/* Needed because we don't declare it yet anywhere */
+void print_file_cb(GtkWidget *file_bt, construct_args_t *args _U_);
+
+/* Forward declaration */
+static void
+savehex_save_clicked_cb(GtkWidget * w, gpointer data);
+
+/* Launch the dialog box to put up the file selection box etc */
+void savehex_cb(GtkWidget * w _U_, gpointer data _U_)
+{
+
+ GtkWidget *dlg_box;
+ GtkWidget *file_box, *file_bt = NULL;
+ GtkWidget *bbox, *save_button, *cancel_button;
+ GtkTooltips *tooltips;
+ static construct_args_t args = {
+ "Save Highlighted Data to File",
+ TRUE,
+ FALSE
+ };
+
+ /* if the window is already open, bring it to front */
+ if(savehex_dlg){
+ gdk_window_raise(savehex_dlg->window);
+ return;
+ }
+
+ tooltips = gtk_tooltips_new();
+
+ /*
+ * Build the dialog box we need ... a text entry field and a
+ * browse button, along with OK and Cancel
+ */
+
+ savehex_dlg=dlg_window_new("Ethereal: Save Highlighted Data to File");
+ SIGNAL_CONNECT(savehex_dlg, "destroy", savehex_dlg_destroy_cb, NULL);
+
+ dlg_box=gtk_vbox_new(FALSE, 10);
+ gtk_container_border_width(GTK_CONTAINER(dlg_box), 10);
+ gtk_container_add(GTK_CONTAINER(savehex_dlg), dlg_box);
+ gtk_widget_show(dlg_box);
+
+ /* File entry box */
+ file_box=gtk_hbox_new(FALSE, 3);
+
+ /* File entry */
+ file_entry=gtk_entry_new();
+ gtk_widget_set_usize(file_entry, 300, -2);
+ gtk_tooltips_set_tip(tooltips, file_entry, ("Enter Save Data filename"), NULL);
+ gtk_box_pack_start(GTK_BOX(file_box), file_entry, TRUE, TRUE, 0);
+ gtk_widget_show(file_entry);
+
+ /* File Browse button */
+ file_bt = gtk_button_new_with_label("Browse:");
+ SIGNAL_CONNECT(file_bt, "clicked", print_file_cb, &args);
+
+ /* file entry for print dialog */
+ OBJECT_SET_DATA(file_bt, E_FILE_TE_PTR_KEY, file_entry);
+ /* file entry for print dialog */
+
+ gtk_tooltips_set_tip (tooltips, file_bt, ("Browse output filename in filesystem"), NULL);
+ gtk_box_pack_start(GTK_BOX(file_box), file_bt, FALSE, TRUE, 0);
+ gtk_widget_show(file_bt);
+
+ gtk_box_pack_start(GTK_BOX(dlg_box), file_box, TRUE, TRUE, 0);
+ gtk_widget_show(file_box);
+
+ /* Now, the button box */
+ bbox=gtk_hbutton_box_new();
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_DEFAULT_STYLE);
+ gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
+ gtk_box_pack_start(GTK_BOX(dlg_box), bbox, FALSE, FALSE, 0);
+ gtk_widget_show(bbox);
+
+ /* the save button */
+ save_button=gtk_button_new_with_label("Save");
+ SIGNAL_CONNECT_OBJECT(save_button, "clicked",
+ savehex_save_clicked_cb, NULL);
+ gtk_box_pack_start(GTK_BOX(bbox), save_button, TRUE, TRUE, 0);
+ GTK_WIDGET_SET_FLAGS(save_button, GTK_CAN_DEFAULT);
+ gtk_widget_grab_default(save_button);
+ gtk_widget_show(save_button);
+
+#if GTK_MAJOR_VERSION < 2
+ cancel_button=gtk_button_new_with_label("Cancel");
+#else
+ cancel_button=gtk_button_new_from_stock(GTK_STOCK_CANCEL);
+#endif
+ SIGNAL_CONNECT(cancel_button, "clicked", savehex_dlg_cancel_cb, savehex_dlg);
+ GTK_WIDGET_SET_FLAGS(cancel_button, GTK_CAN_DEFAULT);
+ gtk_box_pack_start(GTK_BOX(bbox), cancel_button, TRUE, TRUE, 0);
+ gtk_widget_show(cancel_button);
+
+ /* Catch the "activate" signal on the filter text entry, so that
+ if the user types Return there, we act as if the "Create Stat"
+ button had been selected, as happens if Return is typed if some
+ widget that *doesn't* handle the Return key has the input
+ focus. */
+ dlg_set_activate(file_entry, save_button);
+
+ /* Catch the "key_press_event" signal in the window, so that we can
+ catch the ESC key being pressed and act as if the "Cancel" button
+ had been selected. */
+ dlg_set_cancel(savehex_dlg, cancel_button);
+
+ /* Give the initial focus to the "File" entry box. */
+ gtk_widget_grab_focus(file_entry);
+
+ gtk_widget_show_all(savehex_dlg);
+}
+
+/* save the current highlighted hex data as hex_raw.dat */
+static void
+savehex_save_clicked_cb(GtkWidget * w _U_, gpointer data _U_)
+{
+ GtkWidget *bv;
+ int fd, start, end, len;
+ const guint8 *data_p = NULL;
+ char *file = NULL;
+
+ file = (char *)gtk_entry_get_text(GTK_ENTRY(file_entry));
+
+ /* Get rid of the dialog box */
+ gtk_widget_destroy(GTK_WIDGET(savehex_dlg));
+ if (!file ||! *file) {
+ return; /* XXX, put up an error box */
+ }
+
+ /* Must check if file name exists first */
+
+ bv = get_notebook_bv_ptr(byte_nb_ptr);
+ if (bv == NULL) {
+ return; /* none ... should complain */
+ }
+ /*
+ * Retrieve the info we need
+ */
+ end = GPOINTER_TO_INT(OBJECT_GET_DATA(bv, E_BYTE_VIEW_START_KEY));
+ start = GPOINTER_TO_INT(OBJECT_GET_DATA(bv, E_BYTE_VIEW_END_KEY));
+ data_p = get_byte_view_data_and_length(GTK_WIDGET(bv), &len);
+
+ if (data_p == NULL || start == -1 || start > end) {
+ printf("No data to save\n"); /* XXX put up an error box */
+ return;
+ }
+
+ fd = open(file, O_WRONLY|O_CREAT|O_TRUNC, 0666);
+ if (fd == -1) { /* XXX - put up an error dialog */
+ perror(file);
+ return;
+ }
+ write(fd, data_p + start, end - start);
+ close(fd);
+}
+
+
#if GTK_MAJOR_VERSION < 2
static void
packet_hex_print_common(GtkText *bv, const guint8 *pd, int len, int bstart,
@@ -1539,3 +1715,4 @@ clear_tree_and_hex_views(void)
gtk_tree_store_clear(GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(tree_view))));
#endif
}
+