From 80e5e0fb15f19da5bc287666eb653e2d4645a782 Mon Sep 17 00:00:00 2001 From: Gerald Combs Date: Mon, 13 Feb 2006 21:25:43 +0000 Subject: Copy over the file open/save code from the Win32 native branch. The Windows-native routines were integrated by inserting #if GTK_MAJOR_VERSION >= 2 && _WIN32 win32_native_routine(GDK_WINDOW_HWND(top_level->window)); return; #endif at the beginning of each GTK+ file routine. There's probably a prettier way to do this. Some of the sizes need to be tweaked in win32-file-dlg.rc, but everything seems to work. Fix up whitespace. svn path=/trunk/; revision=17285 --- Makefile.am | 1 + Makefile.nmake | 2 +- gtk/Makefile.am | 4 +- gtk/Makefile.nmake | 3 +- gtk/file_dlg.c | 97 ++-- gtk/print_dlg.c | 47 +- gtk/proto_draw.c | 50 +- gtk/win32-file-dlg.c | 1453 +++++++++++++++++++++++++++++++++++++++++++++++ gtk/win32-file-dlg.h | 133 +++++ image/ethereal.rc.in | 2 + image/win32-file-dlg.rc | 135 +++++ 11 files changed, 1864 insertions(+), 63 deletions(-) create mode 100755 gtk/win32-file-dlg.c create mode 100755 gtk/win32-file-dlg.h create mode 100755 image/win32-file-dlg.rc diff --git a/Makefile.am b/Makefile.am index 40f2ffc2b2..921a778d40 100644 --- a/Makefile.am +++ b/Makefile.am @@ -662,6 +662,7 @@ EXTRA_DIST = \ image/icon_layout_4.xpm \ image/icon_layout_5.xpm \ image/icon_layout_6.xpm \ + image/win32-file-dlg.rc \ image/wiretap.rc.in \ make-authors-format.pl \ make-authors-short.pl \ diff --git a/Makefile.nmake b/Makefile.nmake index 24507787ee..1268f2b1dd 100644 --- a/Makefile.nmake +++ b/Makefile.nmake @@ -46,7 +46,7 @@ EXTRA_OBJECTS = \ strptime.obj ethereal_LIBS= wiretap\wiretap-$(WTAP_VERSION).lib \ - wsock32.lib user32.lib shell32.lib \ + wsock32.lib user32.lib shell32.lib comctl32.lib \ $(NET_SNMP_DIR)\win32\lib\release\netsnmp.lib \ !IFDEF ENABLE_LIBETHEREAL epan\libethereal.lib \ diff --git a/gtk/Makefile.am b/gtk/Makefile.am index c4286fa44d..8e26b978b0 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -127,7 +127,9 @@ EXTRA_DIST = \ Makefile.common \ Makefile.nmake \ print_mswin.c \ - print_mswin.h + print_mswin.h \ + win32-file-dlg.c \ + win32-file-dlg.h # Common headers AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/wiretap diff --git a/gtk/Makefile.nmake b/gtk/Makefile.nmake index f7039d6ddf..e4a1bdce45 100644 --- a/gtk/Makefile.nmake +++ b/gtk/Makefile.nmake @@ -28,7 +28,8 @@ include Makefile.common # if you add files here, be sure to include them also in Makefile.am EXTRA_DIST ETHEREAL_WIN32_GTK_SRC = \ $(ETHEREAL_GTK_SRC) \ - print_mswin.c + print_mswin.c \ + win32-file-dlg.c ETHEREAL_TAP_OBJECTS = $(ETHEREAL_TAP_SRC:.c=.obj) diff --git a/gtk/file_dlg.c b/gtk/file_dlg.c index 5943bcb00c..c3b31b265f 100644 --- a/gtk/file_dlg.c +++ b/gtk/file_dlg.c @@ -63,6 +63,12 @@ #include #endif +#if GTK_MAJOR_VERSION >= 2 && _WIN32 +#include +#include +#include "win32-file-dlg.h" +#endif + static void file_open_ok_cb(GtkWidget *w, gpointer fs); static void file_open_destroy_cb(GtkWidget *win, gpointer user_data); static void file_merge_ok_cb(GtkWidget *w, gpointer fs); @@ -209,7 +215,7 @@ preview_do(GtkWidget *prev, wtap *wth) time(&time_preview); while ( (wtap_read(wth, &err, &err_info, &data_offset)) ) { - phdr = wtap_phdr(wth); + phdr = wtap_phdr(wth); cur_time = nstime_to_sec( (const nstime_t *) &phdr->ts ); if(packets == 0) { start_time = cur_time; @@ -271,10 +277,10 @@ preview_do(GtkWidget *prev, wtap *wth) /* elapsed time */ elapsed_time = (unsigned int)(stop_time-start_time); if(elapsed_time/86400) { - g_snprintf(string_buff, PREVIEW_STR_MAX, "%02u days %02u:%02u:%02u", + g_snprintf(string_buff, PREVIEW_STR_MAX, "%02u days %02u:%02u:%02u", elapsed_time/86400, elapsed_time%86400/3600, elapsed_time%3600/60, elapsed_time%60); } else { - g_snprintf(string_buff, PREVIEW_STR_MAX, "%02u:%02u:%02u", + g_snprintf(string_buff, PREVIEW_STR_MAX, "%02u:%02u:%02u", elapsed_time%86400/3600, elapsed_time%3600/60, elapsed_time%60); } if(is_breaked) { @@ -426,6 +432,7 @@ file_open_cmd(GtkWidget *w) #if GTK_MAJOR_VERSION < 2 GtkAccelGroup *accel_group; #endif + /* No Apply button, and "OK" just sets our text widget, it doesn't activate it (i.e., it doesn't cause us to try to open the file). */ static construct_args_t args = { @@ -435,6 +442,11 @@ file_open_cmd(GtkWidget *w) TRUE }; +#if GTK_MAJOR_VERSION >= 2 && _WIN32 + win32_open_file(GDK_WINDOW_HWND(top_level->window)); + return; +#endif + if (file_open_w != NULL) { /* There's already an "Open Capture File" dialog box; reactivate it. */ reactivate_window(file_open_w); @@ -444,7 +456,7 @@ file_open_cmd(GtkWidget *w) file_open_w = file_selection_new("Ethereal: Open Capture File", FILE_SELECTION_OPEN); #if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2 - /* it's annoying, that the file chooser dialog is already shown here, + /* it's annoying, that the file chooser dialog is already shown here, so we cannot use the correct gtk_window_set_default_size() to resize it */ WIDGET_SET_SIZE(GTK_WINDOW(file_open_w), DEF_WIDTH, DEF_HEIGHT); #else @@ -479,7 +491,7 @@ file_open_cmd(GtkWidget *w) break; } - + main_hb = gtk_hbox_new(FALSE, 3); file_selection_set_extra_widget(file_open_w, main_hb); gtk_widget_show(main_hb); @@ -563,7 +575,7 @@ file_open_cmd(GtkWidget *w) gtk_box_pack_start(GTK_BOX(main_hb), prev, TRUE, TRUE, 0); #if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2 - SIGNAL_CONNECT(GTK_FILE_CHOOSER(file_open_w), "selection-changed", + SIGNAL_CONNECT(GTK_FILE_CHOOSER(file_open_w), "selection-changed", file_open_entry_changed, file_open_w); file_open_entry_changed(file_open_w, file_open_w); @@ -575,7 +587,7 @@ file_open_cmd(GtkWidget *w) } else window_destroy(file_open_w); #else - SIGNAL_CONNECT(GTK_FILE_SELECTION(file_open_w)->selection_entry, "changed", + SIGNAL_CONNECT(GTK_FILE_SELECTION(file_open_w)->selection_entry, "changed", file_open_entry_changed, file_open_w); /* Connect the ok_button to file_open_ok_cb function and pass along a @@ -587,7 +599,7 @@ file_open_cmd(GtkWidget *w) E_DFILTER_TE_KEY, OBJECT_GET_DATA(w, E_DFILTER_TE_KEY)); /* Connect the cancel_button to destroy the widget */ - window_set_cancel_button(file_open_w, + window_set_cancel_button(file_open_w, GTK_FILE_SELECTION(file_open_w)->cancel_button, window_cancel_button_cb); SIGNAL_CONNECT(file_open_w, "delete_event", window_delete_event_cb, NULL); @@ -765,6 +777,11 @@ file_merge_cmd(GtkWidget *w) TRUE }; +#if GTK_MAJOR_VERSION >= 2 && _WIN32 + win32_merge_file(GDK_WINDOW_HWND(top_level->window)); + return; +#endif + if (file_merge_w != NULL) { /* There's already an "Merge Capture File" dialog box; reactivate it. */ reactivate_window(file_merge_w); @@ -777,7 +794,7 @@ file_merge_cmd(GtkWidget *w) file_merge_w = file_selection_new("Ethereal: Merge with Capture File", FILE_SELECTION_OPEN); #if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2 - /* it's annoying, that the file chooser dialog is already shown here, + /* it's annoying, that the file chooser dialog is already shown here, so we cannot use the correct gtk_window_set_default_size() to resize it */ WIDGET_SET_SIZE(GTK_WINDOW(file_merge_w), DEF_WIDTH, DEF_HEIGHT); #else @@ -811,7 +828,7 @@ file_merge_cmd(GtkWidget *w) file_selection_set_current_folder(file_merge_w, prefs.gui_fileopen_dir); break; } - + main_hb = gtk_hbox_new(FALSE, 3); file_selection_set_extra_widget(file_merge_w, main_hb); gtk_widget_show(main_hb); @@ -864,7 +881,7 @@ file_merge_cmd(GtkWidget *w) #endif prepend_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(NULL, "Prepend packets to existing file", accel_group); - gtk_tooltips_set_tip(tooltips, prepend_rb, + gtk_tooltips_set_tip(tooltips, prepend_rb, "The resulting file contains the packets from the selected, followed by the packets from the currently loaded file," " the packet timestamps will be ignored.", NULL); gtk_box_pack_start(GTK_BOX(main_vb), prepend_rb, FALSE, FALSE, 0); @@ -878,7 +895,7 @@ file_merge_cmd(GtkWidget *w) gtk_widget_show(prepend_rb); chrono_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(prepend_rb, "Merge packets chronologically", accel_group); - gtk_tooltips_set_tip(tooltips, chrono_rb, + gtk_tooltips_set_tip(tooltips, chrono_rb, "The resulting file contains all the packets from the currently loaded and the selected file," " sorted by the packet timestamps.", NULL); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chrono_rb), TRUE); @@ -892,7 +909,7 @@ file_merge_cmd(GtkWidget *w) #endif append_rb = RADIO_BUTTON_NEW_WITH_MNEMONIC(prepend_rb, "Append packets to existing file", accel_group); - gtk_tooltips_set_tip(tooltips, append_rb, + gtk_tooltips_set_tip(tooltips, append_rb, "The resulting file contains the packets from the currently loaded, followed by the packets from the selected file," " the packet timestamps will be ignored.", NULL); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(append_rb), @@ -916,7 +933,7 @@ file_merge_cmd(GtkWidget *w) gtk_box_pack_start(GTK_BOX(main_hb), prev, TRUE, TRUE, 0); #if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2 - SIGNAL_CONNECT(GTK_FILE_CHOOSER(file_merge_w), "selection-changed", + SIGNAL_CONNECT(GTK_FILE_CHOOSER(file_merge_w), "selection-changed", file_open_entry_changed, file_merge_w); file_open_entry_changed(file_merge_w, file_merge_w); @@ -928,7 +945,7 @@ file_merge_cmd(GtkWidget *w) } else window_destroy(file_merge_w); #else - SIGNAL_CONNECT(GTK_FILE_SELECTION(file_merge_w)->selection_entry, "changed", + SIGNAL_CONNECT(GTK_FILE_SELECTION(file_merge_w)->selection_entry, "changed", file_open_entry_changed, file_merge_w); /* Connect the ok_button to file_merge_ok_cb function and pass along a @@ -940,7 +957,7 @@ file_merge_cmd(GtkWidget *w) E_DFILTER_TE_KEY, OBJECT_GET_DATA(w, E_DFILTER_TE_KEY)); /* Connect the cancel_button to destroy the widget */ - window_set_cancel_button(file_merge_w, + window_set_cancel_button(file_merge_w, GTK_FILE_SELECTION(file_merge_w)->cancel_button, window_cancel_button_cb); SIGNAL_CONNECT(file_merge_w, "delete_event", window_delete_event_cb, NULL); @@ -1042,7 +1059,7 @@ file_merge_ok_cb(GtkWidget *w, gpointer fs) { } g_free(cf_name); - + if (merge_status != CF_OK) { if (rfcode != NULL) dfilter_free(rfcode); @@ -1224,7 +1241,7 @@ file_save_update_dynamics(void) /* We don't currently have a "Save As..." dialog box up. */ return; } - + range_update_dynamics(range_tb); } @@ -1242,7 +1259,12 @@ file_save_as_cmd(action_after_save_e action_after_save, gpointer action_after_sa #if GTK_MAJOR_VERSION < 2 GtkAccelGroup *accel_group; #endif - + +#if GTK_MAJOR_VERSION >= 2 && _WIN32 + win32_save_as_file(GDK_WINDOW_HWND(top_level->window), action_after_save, action_after_save_data); + return; +#endif + if (file_save_as_w != NULL) { /* There's already an "Save Capture File As" dialog box; reactivate it. */ reactivate_window(file_save_as_w); @@ -1257,7 +1279,7 @@ file_save_as_cmd(action_after_save_e action_after_save, gpointer action_after_sa /* Enable tooltips */ tooltips = gtk_tooltips_new(); - + /* build the file selection */ file_save_as_w = file_selection_new ("Ethereal: Save Capture File As", FILE_SELECTION_SAVE); @@ -1271,19 +1293,19 @@ file_save_as_cmd(action_after_save_e action_after_save, gpointer action_after_sa accel_group = gtk_accel_group_new(); gtk_window_add_accel_group(GTK_WINDOW(file_save_as_w), accel_group); #endif - + /* Container for each row of widgets */ - + main_vb = gtk_vbox_new(FALSE, 5); gtk_container_border_width(GTK_CONTAINER(main_vb), 5); file_selection_set_extra_widget(file_save_as_w, main_vb); - gtk_widget_show(main_vb); - + gtk_widget_show(main_vb); + /*** Packet Range frame ***/ range_fr = gtk_frame_new("Packet Range"); gtk_box_pack_start(GTK_BOX(main_vb), range_fr, FALSE, FALSE, 0); gtk_widget_show(range_fr); - + /* range table */ range_tb = range_new(&range #if GTK_MAJOR_VERSION < 2 @@ -1315,7 +1337,7 @@ file_save_as_cmd(action_after_save_e action_after_save, gpointer action_after_sa /* compressed */ compressed_cb = gtk_check_button_new_with_label("Compress with gzip"); gtk_container_add(GTK_CONTAINER(ft_hb), compressed_cb); - /* XXX - disable output compression for now, as this doesn't work with the + /* XXX - disable output compression for now, as this doesn't work with the * current optimization to simply copy a capture file if it's using the same * encapsulation ... */ /* the rest of the implementation is just working fine :-( */ @@ -1337,7 +1359,7 @@ file_save_as_cmd(action_after_save_e action_after_save, gpointer action_after_sa SIGNAL_CONNECT(GTK_FILE_SELECTION (file_save_as_w)->ok_button, "clicked", file_save_as_ok_cb, file_save_as_w); - window_set_cancel_button(file_save_as_w, + window_set_cancel_button(file_save_as_w, GTK_FILE_SELECTION(file_save_as_w)->cancel_button, window_cancel_button_cb); SIGNAL_CONNECT(file_save_as_w, "delete_event", window_delete_event_cb, NULL); @@ -1373,7 +1395,7 @@ file_save_as_cb(GtkWidget *w _U_, gpointer fs) { /* Write out the packets (all, or only the ones from the current range) to the file with the specified name. */ - if (cf_save(&cfile, cf_name, &range, filetype, + if (cf_save(&cfile, cf_name, &range, filetype, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(compressed_cb))) != CF_OK) { /* The write failed; don't dismiss the open dialog box, just leave it around so that the user can, after they @@ -1465,7 +1487,7 @@ static void file_save_as_ok_cb(GtkWidget *w _U_, gpointer fs) { gchar *cf_name; gpointer dialog; - + #if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2 cf_name = g_strdup(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fs))); #else @@ -1602,6 +1624,12 @@ file_color_import_cmd_cb(GtkWidget *w _U_, gpointer data) #if GTK_MAJOR_VERSION < 2 GtkAccelGroup *accel_group; #endif + +#if GTK_MAJOR_VERSION >= 2 && _WIN32 + win32_import_color_file(GDK_WINDOW_HWND(top_level->window)); + return; +#endif + /* No Apply button, and "OK" just sets our text widget, it doesn't activate it (i.e., it doesn't cause us to try to open the file). */ @@ -1653,7 +1681,7 @@ file_color_import_cmd_cb(GtkWidget *w _U_, gpointer data) OBJECT_SET_DATA(GTK_FILE_SELECTION(file_color_import_w)->ok_button, ARGUMENT_CL, data); - window_set_cancel_button(file_color_import_w, + window_set_cancel_button(file_color_import_w, GTK_FILE_SELECTION(file_color_import_w)->cancel_button, window_cancel_button_cb); SIGNAL_CONNECT(file_color_import_w, "delete_event", window_delete_event_cb, NULL); @@ -1670,7 +1698,7 @@ file_color_import_ok_cb(GtkWidget *w, gpointer fs) { gpointer argument; argument = OBJECT_GET_DATA(w, ARGUMENT_CL); /* to be passed back into color_filters_import */ - + #if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2 cf_name = g_strdup(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fs))); #else @@ -1758,6 +1786,11 @@ file_color_export_cmd_cb(GtkWidget *w _U_, gpointer data _U_) { GtkWidget *main_vb, *cfglobal_but; +#if GTK_MAJOR_VERSION >= 2 && _WIN32 + win32_export_color_file(GDK_WINDOW_HWND(top_level->window)); + return; +#endif + if (file_color_export_w != NULL) { /* There's already an "Color Filter Export" dialog box; reactivate it. */ reactivate_window(file_color_export_w); @@ -1803,7 +1836,7 @@ file_color_export_cmd_cb(GtkWidget *w _U_, gpointer data _U_) SIGNAL_CONNECT(GTK_FILE_SELECTION (file_color_export_w)->ok_button, "clicked", file_color_export_ok_cb, file_color_export_w); - window_set_cancel_button(file_color_export_w, + window_set_cancel_button(file_color_export_w, GTK_FILE_SELECTION(file_color_export_w)->cancel_button, window_cancel_button_cb); SIGNAL_CONNECT(file_color_export_w, "delete_event", window_delete_event_cb, NULL); diff --git a/gtk/print_dlg.c b/gtk/print_dlg.c index fd63f4b8fe..a301b35e25 100644 --- a/gtk/print_dlg.c +++ b/gtk/print_dlg.c @@ -31,6 +31,7 @@ #include #include "globals.h" +#include "gtkglobals.h" #include "keys.h" #include "print.h" #include @@ -51,6 +52,11 @@ #include "file_util.h" #include "util.h" +#if GTK_MAJOR_VERSION >= 2 && _WIN32 +#include +#include +#include "win32-file-dlg.h" +#endif /* dialog output action */ typedef enum { @@ -144,7 +150,7 @@ file_print_cmd(gboolean print_selected) if(print_selected) { args->range.process = range_process_selected; } - + print_win = open_print_dialog("Ethereal: Print", output_action_print, args); SIGNAL_CONNECT(print_win, "destroy", print_destroy_cb, &print_win); } @@ -178,6 +184,11 @@ export_text_cmd_cb(GtkWidget *widget _U_, gpointer data _U_) { print_args_t *args = &export_text_args; +#if GTK_MAJOR_VERSION >= 2 && _WIN32 + win32_export_file(GDK_WINDOW_HWND(top_level->window), export_type_text); + return; +#endif + if (export_text_win != NULL) { /* There's already a "Export text" dialog box; reactivate it. */ reactivate_window(export_text_win); @@ -196,7 +207,7 @@ export_text_cmd_cb(GtkWidget *widget _U_, gpointer data _U_) args->print_hex = FALSE; args->print_formfeed = FALSE; } - + /* init the printing range */ packet_range_init(&args->range); @@ -222,6 +233,11 @@ export_ps_cmd_cb(GtkWidget *widget _U_, gpointer data _U_) { print_args_t *args = &export_ps_args; +#if GTK_MAJOR_VERSION >= 2 && _WIN32 + win32_export_file(GDK_WINDOW_HWND(top_level->window), export_type_ps); + return; +#endif + if (export_ps_win != NULL) { /* There's already a "Export ps" dialog box; reactivate it. */ reactivate_window(export_ps_win); @@ -240,7 +256,7 @@ export_ps_cmd_cb(GtkWidget *widget _U_, gpointer data _U_) args->print_hex = FALSE; args->print_formfeed = FALSE; } - + /* init the printing range */ packet_range_init(&args->range); @@ -266,6 +282,11 @@ export_psml_cmd_cb(GtkWidget *widget _U_, gpointer data _U_) { print_args_t *args = &export_psml_args; +#if GTK_MAJOR_VERSION >= 2 && _WIN32 + win32_export_file(GDK_WINDOW_HWND(top_level->window), export_type_psml); + return; +#endif + if (export_psml_win != NULL) { /* There's already a "Export psml" dialog box; reactivate it. */ reactivate_window(export_psml_win); @@ -284,7 +305,7 @@ export_psml_cmd_cb(GtkWidget *widget _U_, gpointer data _U_) args->print_hex = FALSE; args->print_formfeed = FALSE; } - + /* init the printing range */ packet_range_init(&args->range); @@ -310,6 +331,11 @@ export_pdml_cmd_cb(GtkWidget *widget _U_, gpointer data _U_) { print_args_t *args = &export_pdml_args; +#if GTK_MAJOR_VERSION >= 2 && _WIN32 + win32_export_file(GDK_WINDOW_HWND(top_level->window), export_type_pdml); + return; +#endif + if (export_pdml_win != NULL) { /* There's already a "Export pdml" dialog box; reactivate it. */ reactivate_window(export_pdml_win); @@ -328,7 +354,7 @@ export_pdml_cmd_cb(GtkWidget *widget _U_, gpointer data _U_) args->print_hex = FALSE; args->print_formfeed = FALSE; } - + /* init the printing range */ packet_range_init(&args->range); @@ -352,6 +378,11 @@ export_csv_cmd_cb(GtkWidget *widget _U_, gpointer data _U_) { print_args_t *args = &export_csv_args; +#if GTK_MAJOR_VERSION >= 2 && _WIN32 + win32_export_file(GDK_WINDOW_HWND(top_level->window), export_type_csv); + return; +#endif + if (export_csv_win != NULL) { /* There's already a "Export csv" dialog box; reactivate it. */ reactivate_window(export_csv_win); @@ -522,7 +553,7 @@ open_print_dialog(const char *title, output_action_e action, print_args_t *args) gtk_table_attach_defaults(GTK_TABLE(printer_tb), dest_cb, 0, 1, 0, 1); if(action == output_action_print) gtk_widget_show(dest_cb); - + /* File text entry */ file_te = gtk_entry_new(); OBJECT_SET_DATA(dest_cb, PRINT_FILE_TE_KEY, file_te); @@ -597,7 +628,7 @@ open_print_dialog(const char *title, output_action_e action, print_args_t *args) /*** packet format frame ***/ format_fr = gtk_frame_new("Packet Format"); gtk_box_pack_start(GTK_BOX(packet_hb), format_fr, TRUE, TRUE, 0); - if( action == output_action_print || + if( action == output_action_print || action == output_action_export_text || action == output_action_export_ps) gtk_widget_show(format_fr); @@ -805,7 +836,7 @@ print_cmd_toggle_detail(GtkWidget *widget _U_, gpointer data) gtk_widget_set_sensitive(expand_all_rb, print_detail); /* if user selected nothing to print at all, disable the "ok" button */ - gtk_widget_set_sensitive(print_bt, + gtk_widget_set_sensitive(print_bt, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (summary_cb)) || gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (details_cb)) || gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (hex_cb))); diff --git a/gtk/proto_draw.c b/gtk/proto_draw.c index 5ef7d99fc5..745c55c0e1 100644 --- a/gtk/proto_draw.c +++ b/gtk/proto_draw.c @@ -71,6 +71,12 @@ #include "../ui_util.h" #include "file_util.h" +#if GTK_MAJOR_VERSION >= 2 && _WIN32 +#include +#include +#include "win32-file-dlg.h" +#endif + #define BYTE_VIEW_WIDTH 16 #define BYTE_VIEW_SEP 8 @@ -223,9 +229,9 @@ redraw_hex_dump_all(void) #if GTK_MAJOR_VERSION >= 2 /* XXX - this is a hack, to workaround a bug in GTK2.x! - when changing the font size, even refilling of the corresponding - gtk_text_buffer doesn't seem to trigger an update. - The only workaround is to freshly select the frame, which will remove any + when changing the font size, even refilling of the corresponding + gtk_text_buffer doesn't seem to trigger an update. + The only workaround is to freshly select the frame, which will remove any existing notebook tabs and "restart" the whole byte view again. */ if (cfile.current_frame != NULL) cf_goto_frame(&cfile, cfile.current_frame->num); @@ -698,7 +704,7 @@ add_byte_tab(GtkWidget *byte_nb, const char *name, tvbuff_t *tvb, /* Horizontal */GTK_POLICY_NEVER, /* Vertical*/ GTK_POLICY_ALWAYS); #else - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(byte_scrollw), + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(byte_scrollw), GTK_SHADOW_IN); #endif /* Add scrolled pane to tabbed window */ @@ -745,7 +751,7 @@ add_byte_tab(GtkWidget *byte_nb, const char *name, tvbuff_t *tvb, gtk_notebook_set_show_tabs(GTK_NOTEBOOK(byte_nb), TRUE); /* set this page (this will print the packet data) */ - gtk_notebook_set_page(GTK_NOTEBOOK(byte_nb), + gtk_notebook_set_page(GTK_NOTEBOOK(byte_nb), gtk_notebook_page_num(GTK_NOTEBOOK(byte_nb), byte_nb)); return byte_view; @@ -797,7 +803,7 @@ savehex_dlg_destroy_cb(void) } void -copy_hex_cb(GtkWidget * w _U_, gpointer data _U_) +copy_hex_cb(GtkWidget * w _U_, gpointer data _U_) { GtkWidget *bv; int len; @@ -805,16 +811,16 @@ copy_hex_cb(GtkWidget * w _U_, gpointer data _U_) const guint8 *data_p = NULL; GString *ASCII_representation = g_string_new(""); GString *byte_str = g_string_new(""); - + bv = get_notebook_bv_ptr(byte_nb_ptr); if (bv == NULL) { - /* shouldn't happen */ + /* shouldn't happen */ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not find the corresponding text window!"); return; } - + data_p = get_byte_view_data_and_length(GTK_WIDGET(bv), &len); - + g_string_sprintfa(byte_str,"%04x ",i); /* Offset 0000 */ for (i=0; ilen){ for (i=ASCII_representation->len; i<16; i++){ g_string_sprintfa(byte_str," "); @@ -866,7 +872,7 @@ savehex_save_clicked_cb(GtkWidget * w _U_, gpointer data _U_) return; } /* - * Retrieve the info we need + * 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)); @@ -902,11 +908,15 @@ void savehex_cb(GtkWidget * w _U_, gpointer data _U_) { int start, end, len; const guint8 *data_p = NULL; - gchar *label; + gchar *label; - GtkWidget *bv; + GtkWidget *bv; GtkWidget *dlg_lb; +#if GTK_MAJOR_VERSION >= 2 && _WIN32 + win32_export_raw_file(GDK_WINDOW_HWND(top_level->window)); + return; +#endif /* don't show up the dialog, if no data has to be saved */ bv = get_notebook_bv_ptr(byte_nb_ptr); @@ -936,7 +946,7 @@ void savehex_cb(GtkWidget * w _U_, gpointer data _U_) savehex_dlg = file_selection_new("Ethereal: Export Selected Packet Bytes", FILE_SELECTION_SAVE); /* label */ - label = g_strdup_printf("Will save %u %s of raw binary data to specified file.", + label = g_strdup_printf("Will save %u %s of raw binary data to specified file.", end - start, plurality(end - start, "byte", "bytes")); dlg_lb = gtk_label_new(label); g_free(label); @@ -957,7 +967,7 @@ void savehex_cb(GtkWidget * w _U_, gpointer data _U_) SIGNAL_CONNECT(GTK_FILE_SELECTION (savehex_dlg)->ok_button, "clicked", savehex_save_clicked_cb, savehex_dlg); - window_set_cancel_button(savehex_dlg, + window_set_cancel_button(savehex_dlg, GTK_FILE_SELECTION(savehex_dlg)->cancel_button, window_cancel_button_cb); SIGNAL_CONNECT(savehex_dlg, "delete_event", window_delete_event_cb, NULL); @@ -1607,7 +1617,7 @@ GdkColor expert_color_note = { 0, 0xa000, 0xff00, 0xff00 }; /* a bright turquois GdkColor expert_color_warn = { 0, 0xff00, 0xff00, 0 }; /* yellow */ GdkColor expert_color_error = { 0, 0xff00, 0x5c00, 0x5c00 }; /* pale red */ -void proto_draw_colors_init(void) +void proto_draw_colors_init(void) { if(colors_ok) { return; @@ -1643,7 +1653,7 @@ static void tree_cell_renderer(GtkTreeViewColumn *tree_column _U_, * color definitions can be found at: * http://cvs.gnome.org/viewcvs/gtk+/gdk-pixbuf/io-xpm.c?rev=1.42 * (a good color overview: http://www.computerhope.com/htmcolor.htm) - * + * * some experiences: * background-gdk: doesn't seem to work (probably the GdkColor must be allocated) * weight/style: doesn't take any effect @@ -1788,7 +1798,7 @@ main_tree_view_new(e_prefs *prefs, GtkWidget **tree_view_p) /* Tree view */ tv_scrollw = scrolled_window_new(NULL, NULL); #if GTK_MAJOR_VERSION >= 2 - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(tv_scrollw), + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(tv_scrollw), GTK_SHADOW_IN); #endif @@ -1920,7 +1930,7 @@ tree_view_select(GtkWidget *widget, GdkEventButton *event) field_info *fi; - if(gtk_clist_get_selection_info(GTK_CLIST(widget), + if(gtk_clist_get_selection_info(GTK_CLIST(widget), (gint) (((GdkEventButton *)event)->x), (gint) (((GdkEventButton *)event)->y), &row, &column)) diff --git a/gtk/win32-file-dlg.c b/gtk/win32-file-dlg.c new file mode 100755 index 0000000000..a539c754a0 --- /dev/null +++ b/gtk/win32-file-dlg.c @@ -0,0 +1,1453 @@ +/* win32-file-dlg.c + * Native Windows file dialog routines + * + * $Id$ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs + * Copyright 2004 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "globals.h" + +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "alert_box.h" +#include "color.h" +#include "color_filters.h" +#include "epan/filesystem.h" +#include "epan/addr_resolv.h" +#include "merge.h" +#include "epan/prefs.h" +#include "print.h" +#include "simple_dialog.h" +#include "util.h" + +// XXX - declarations from gtk/file_dlg.h. These should be moved +// somewhere less GTK-specific. +/** the action to take, after save has been done */ +typedef enum { + after_save_no_action, /**< no action to take */ + after_save_close_file, /**< close the file */ + after_save_open_dialog, /**< open the file open dialog */ + after_save_open_recent_file, /**< open the specified recent file */ + after_save_open_dnd_file, /**< open the specified file from drag and drop */ + after_save_merge_dialog, /**< open the file merge dialog */ + after_save_capture_dialog, /**< open the capture dialog */ + after_save_exit /**< exit program */ +} action_after_save_e; + +#include "win32-file-dlg.h" + +// XXX - declarations from gtk/dlg_utils.h. These should be moved +// somewhere less GTK-specific. +extern void set_last_open_dir(char *dirname); + +// XXX - declarations from gtk/capture_dlg.h. These should be moved +// somewhere less GTK-specific. +/* capture start confirmed by "Save unsaved capture", so do it now */ +void capture_start_confirmed(void); + +// gtk/main.h: +extern gboolean main_do_quit(void); + + + + +typedef enum { + merge_append, + merge_chrono, + merge_prepend +} merge_action_e; + +#define FILE_TYPE_LIST \ + "Accellent 5Views (*.5vw)\0" "*.5vw\0" \ + "Ethereal/tcpdump (*.cap, *.pcap)\0" "*.cap;*.pcap\0" \ + "Novell LANalyzer (*.tr1)\0" "*.tr1\0" \ + "NG/NAI Sniffer (*.cap, *.enc, *.trc)\0" "*.cap;*.enc;*.trc\0" \ + "Sun snoop (*.snoop)\0" "*.snoop\0" \ + "WildPackets EtherPeek (*.pkt)\0" "*.pkt\0" \ + "All Files (*.*)\0" "*.*\0" \ + "\0" + +#define FILE_TYPE_DEFAULT 2 /* Ethereal/tcpdump */ + + +static UINT CALLBACK open_file_hook_proc(HWND of_hwnd, UINT ui_msg, WPARAM w_param, LPARAM l_param); +static UINT CALLBACK save_as_file_hook_proc(HWND of_hwnd, UINT ui_msg, WPARAM w_param, LPARAM l_param); +static UINT CALLBACK merge_file_hook_proc(HWND mf_hwnd, UINT ui_msg, WPARAM w_param, LPARAM l_param); +static UINT CALLBACK export_file_hook_proc(HWND of_hwnd, UINT ui_msg, WPARAM w_param, LPARAM l_param); +static UINT CALLBACK export_raw_file_hook_proc(HWND of_hwnd, UINT ui_msg, WPARAM w_param, LPARAM l_param); +static void range_update_dynamics(HWND sf_hwnd, packet_range_t *range); +static void range_handle_wm_initdialog(HWND dlg_hwnd, packet_range_t *range); +static void range_handle_wm_command(HWND dlg_hwnd, HWND ctrl, WPARAM w_param, packet_range_t *range); + +static gboolean initialized = FALSE; +static int filetype; +static packet_range_t range; +static merge_action_e merge_action; +static print_args_t print_args; +/* XXX - The reason g_sf_hwnd exists is so that we can call + * file_set_save_marked_sensitive() from anywhere. However, the + * save file dialog hogs the foreground, so this may not be + * necessary. + */ +static HWND g_sf_hwnd = NULL; + +static void +win32_file_init() { + INITCOMMONCONTROLSEX comm_ctrl; + + if (initialized) + return; + initialized = TRUE; + + /* Initialize our controls. */ + memset (&comm_ctrl, 0, sizeof(comm_ctrl)); + comm_ctrl.dwSize = sizeof(comm_ctrl); + /* Includes the animate, header, hot key, list view, progress bar, + * status bar, tab, tooltip, toolbar, trackbar, tree view, and + * up-down controls + */ + comm_ctrl.dwICC = ICC_WIN95_CLASSES; + InitCommonControlsEx(&comm_ctrl); + + /* RichEd20.DLL is needed for filter entries. */ + LoadLibrary("riched20.dll"); +} + +gboolean +win32_open_file (HWND h_wnd) { + static OPENFILENAME ofn; + gchar file_name[MAX_PATH] = ""; + int err; + char *dirname; + + win32_file_init(); + + /* XXX - Check for version and set OPENFILENAME_SIZE_VERSION_400 + where appropriate */ + ZeroMemory(&ofn, sizeof(ofn)); +#ifdef OPENFILENAME_SIZE_VERSION_400 + of.lStructSize = OPENFILENAME_SIZE_VERSION_400; +#else + ofn.lStructSize = sizeof(ofn); +#endif + ofn.hwndOwner = h_wnd; + ofn.hInstance = (HINSTANCE) GetWindowLong(h_wnd, GWL_HINSTANCE); + /* XXX - Grab the rest of the extension list from ethereal.nsi. */ + ofn.lpstrFilter = FILE_TYPE_LIST; + ofn.lpstrCustomFilter = NULL; + ofn.nMaxCustFilter = 0; + ofn.nFilterIndex = FILE_TYPE_DEFAULT; + ofn.lpstrFile = file_name; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + if (prefs.gui_fileopen_style == FO_STYLE_SPECIFIED && prefs.gui_fileopen_dir[0] != '\0') { + ofn.lpstrInitialDir = prefs.gui_fileopen_dir; + } else { + ofn.lpstrInitialDir = NULL; + } + ofn.lpstrTitle = "Ethereal: Select a capture file"; + ofn.Flags = OFN_ENABLESIZING | OFN_ENABLETEMPLATE | OFN_EXPLORER | + OFN_NOCHANGEDIR | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | + OFN_ENABLEHOOK; + ofn.lpstrDefExt = NULL; + ofn.lpfnHook = open_file_hook_proc; + ofn.lpTemplateName = "ETHEREAL_OPENFILENAME_TEMPLATE"; + + /* XXX - Get our filter */ + + if (GetOpenFileName(&ofn)) { + if (cf_open(&cfile, file_name, FALSE, &err) != CF_OK) { + epan_cleanup(); + exit(2); + } + switch (cf_read(&cfile)) { + case CF_READ_OK: + case CF_READ_ERROR: + dirname = get_dirname(file_name); + set_last_open_dir(dirname); +// menu_name_resolution_changed(h_wnd); + return TRUE; + break; + } + } + return FALSE; +} + + +void +win32_save_as_file(HWND h_wnd, action_after_save_e action_after_save, gpointer action_after_save_data) { + static OPENFILENAME ofn; + gchar file_name[MAX_PATH] = ""; + gchar *dirname; + + /* XXX - Check for version and set OPENFILENAME_SIZE_VERSION_400 + where appropriate */ + ZeroMemory(&ofn, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = h_wnd; + ofn.hInstance = (HINSTANCE) GetWindowLong(h_wnd, GWL_HINSTANCE); + /* XXX - Grab the rest of the extension list from ethereal.nsi. */ + ofn.lpstrFilter = FILE_TYPE_LIST; + ofn.lpstrCustomFilter = NULL; + ofn.nMaxCustFilter = 0; + ofn.nFilterIndex = FILE_TYPE_DEFAULT; + ofn.lpstrFile = file_name; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + if (prefs.gui_fileopen_style == FO_STYLE_SPECIFIED && prefs.gui_fileopen_dir[0] != '\0') { + ofn.lpstrInitialDir = prefs.gui_fileopen_dir; + } else { + ofn.lpstrInitialDir = NULL; + } + ofn.lpstrTitle = "Ethereal: Save file as"; + ofn.Flags = OFN_ENABLESIZING | OFN_ENABLETEMPLATE | OFN_EXPLORER | + OFN_NOCHANGEDIR | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | + OFN_PATHMUSTEXIST | OFN_ENABLEHOOK; + ofn.lpstrDefExt = NULL; + ofn.lpfnHook = save_as_file_hook_proc; + ofn.lpTemplateName = "ETHEREAL_SAVEFILENAME_TEMPLATE"; + + if (GetSaveFileName(&ofn)) { + g_sf_hwnd = NULL; + /* Write out the packets (all, or only the ones from the current + range) to the file with the specified name. */ + /* XXX - If we're overwriting a file, GetSaveFileName does the + standard windows confirmation. cf_save() then rejects the overwrite. */ + if (cf_save(&cfile, file_name, &range, filetype, FALSE) != CF_OK) { + /* The write failed. Try again. */ + win32_save_as_file(h_wnd, action_after_save, action_after_save_data); + return; + } + + /* Save the directory name for future file dialogs. */ + dirname = get_dirname(file_name); /* Overwrites cf_name */ + set_last_open_dir(dirname); + + /* we have finished saving, do we have pending things to do? */ + switch(action_after_save) { + case(after_save_no_action): + break; + case(after_save_open_dialog): + win32_open_file(h_wnd); + break; + case(after_save_open_recent_file): +// menu_open_recent_file_cmd(action_after_save_data_g); + break; + case(after_save_open_dnd_file): +// dnd_open_file_cmd(action_after_save_data_g); + break; + case(after_save_merge_dialog): +// file_merge_cmd(action_after_save_data_g); + break; +#ifdef HAVE_LIBPCAP + case(after_save_capture_dialog): + capture_start_confirmed(); + break; +#endif + case(after_save_close_file): + cf_close(&cfile); + break; + case(after_save_exit): + main_do_quit(); + break; + default: + g_assert_not_reached(); + } + } + g_sf_hwnd = NULL; +} + + +void +win32_merge_file (HWND h_wnd) { + static OPENFILENAME ofn; + gchar file_name[MAX_PATH] = ""; + char *dirname; + cf_status_t merge_status; + char *in_filenames[2]; + int err; + char *tmpname; + + /* XXX - Check for temp file and prompt accordingly */ + + /* XXX - Check for version and set OPENFILENAME_SIZE_VERSION_400 + where appropriate */ + ZeroMemory(&ofn, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = h_wnd; + ofn.hInstance = (HINSTANCE) GetWindowLong(h_wnd, GWL_HINSTANCE); + /* XXX - Grab the rest of the extension list from ethereal.nsi. */ + ofn.lpstrFilter = FILE_TYPE_LIST; + ofn.lpstrCustomFilter = NULL; + ofn.nMaxCustFilter = 0; + ofn.nFilterIndex = FILE_TYPE_DEFAULT; + ofn.lpstrFile = file_name; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + if (prefs.gui_fileopen_style == FO_STYLE_SPECIFIED && prefs.gui_fileopen_dir[0] != '\0') { + ofn.lpstrInitialDir = prefs.gui_fileopen_dir; + } else { + ofn.lpstrInitialDir = NULL; + } + ofn.lpstrTitle = "Ethereal: Merge with capture file"; + ofn.Flags = OFN_ENABLESIZING | OFN_ENABLETEMPLATE | OFN_EXPLORER | + OFN_NOCHANGEDIR | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | + OFN_ENABLEHOOK; + ofn.lpstrDefExt = NULL; + ofn.lpfnHook = merge_file_hook_proc; + ofn.lpTemplateName = "ETHEREAL_MERGEFILENAME_TEMPLATE"; + + if (GetOpenFileName(&ofn)) { + filetype = cfile.cd_t; + + /* merge or append the two files */ + + tmpname = NULL; + switch (merge_action) { + case merge_append: + /* append file */ + in_filenames[0] = file_name; + in_filenames[1] = cfile.filename; + merge_status = cf_merge_files(&tmpname, 2, in_filenames, filetype, TRUE); + break; + case merge_chrono: + /* chonological order */ + in_filenames[0] = cfile.filename; + in_filenames[1] = file_name; + merge_status = cf_merge_files(&tmpname, 2, in_filenames, filetype, FALSE); + break; + case merge_prepend: + /* prepend file */ + in_filenames[0] = cfile.filename; + in_filenames[1] = file_name; + merge_status = cf_merge_files(&tmpname, 2, in_filenames, filetype, TRUE); + break; + default: + g_assert_not_reached(); + } + + if(merge_status != CF_OK) { + /* merge failed */ + g_free(tmpname); +// if (rfcode != NULL) +// dfilter_free(rfcode); + return; + } + + cf_close(&cfile); + + /* Try to open the merged capture file. */ + if (cf_open(&cfile, tmpname, TRUE /* temporary file */, &err) != CF_OK) { + /* We couldn't open it; don't dismiss the open dialog box, + just leave it around so that the user can, after they + dismiss the alert box popped up for the open error, + try again. */ +// if (rfcode != NULL) +// dfilter_free(rfcode); + return; + } + + /* Attach the new read filter to "cf" ("cf_open()" succeeded, so + it closed the previous capture file, and thus destroyed any + previous read filter attached to "cf"). */ +// cfile.rfcode = rfcode; + + switch (cf_read(&cfile)) { + case CF_READ_OK: + case CF_READ_ERROR: + dirname = get_dirname(file_name); + set_last_open_dir(dirname); +// menu_name_resolution_changed(h_wnd); + break; + case CF_READ_ABORTED: + break; + } + + } else if (CommDlgExtendedError() != 0) { + sprintf(file_name, "failed: %d/%d (%p)", CommDlgExtendedError(), GetLastError(), h_wnd); + MessageBox(NULL, file_name, "Eth", MB_OK); + } +} + +void +win32_export_file(HWND h_wnd, export_type_e export_type) { + static OPENFILENAME ofn; + gchar file_name[MAX_PATH] = ""; + char *dirname; + cf_print_status_t status; + + /* XXX - Check for version and set OPENFILENAME_SIZE_VERSION_400 + where appropriate */ + ZeroMemory(&ofn, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = h_wnd; + ofn.hInstance = (HINSTANCE) GetWindowLong(h_wnd, GWL_HINSTANCE); + ofn.lpstrFilter = + "Plain text (*.txt)\0" "*.txt\0" + "PostScript (*.ps)\0" "*.ps\0" + "CSV (Comma Separated Values summary (*.csv)\0" "*.csv\0" + "PSML (XML packet summary) (*.psml)\0" "*.psml\0" + "PDML (XML packet detail) (*.pdml)\0" "*.pdml\0" + "\0"; + ofn.lpstrCustomFilter = NULL; + ofn.nMaxCustFilter = 0; + ofn.nFilterIndex = export_type; + ofn.lpstrFile = file_name; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + if (prefs.gui_fileopen_style == FO_STYLE_SPECIFIED && prefs.gui_fileopen_dir[0] != '\0') { + ofn.lpstrInitialDir = prefs.gui_fileopen_dir; + } else { + ofn.lpstrInitialDir = NULL; + } + ofn.lpstrTitle = "Ethereal: Export"; + ofn.Flags = OFN_ENABLESIZING | OFN_ENABLETEMPLATE | OFN_EXPLORER | + OFN_NOCHANGEDIR | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | + OFN_PATHMUSTEXIST | OFN_ENABLEHOOK; + ofn.lpstrDefExt = NULL; + ofn.lpfnHook = export_file_hook_proc; + ofn.lpTemplateName = "ETHEREAL_EXPORTFILENAME_TEMPLATE"; + + /* Fill in our print (and export) args */ + + print_args.format = PR_FMT_TEXT; + print_args.to_file = TRUE; + print_args.file = file_name; + print_args.cmd = NULL; + print_args.print_summary = TRUE; + print_args.print_dissections = print_dissections_as_displayed; + print_args.print_hex = FALSE; + print_args.print_formfeed = FALSE; + + if (GetSaveFileName(&ofn)) { + switch (ofn.nFilterIndex) { + case export_type_text: /* Text */ + print_args.stream = print_stream_text_new(TRUE, print_args.file); + if (print_args.stream == NULL) { + open_failure_alert_box(print_args.file, errno, TRUE); + return; + } + status = cf_print_packets(&cfile, &print_args); + break; + case export_type_ps: /* PostScript (r) */ + print_args.stream = print_stream_ps_new(TRUE, print_args.file); + if (print_args.stream == NULL) { + open_failure_alert_box(print_args.file, errno, TRUE); + return; + } + status = cf_print_packets(&cfile, &print_args); + break; + case export_type_csv: /* CSV */ + status = cf_write_csv_packets(&cfile, &print_args); + break; + case export_type_psml: /* PSML */ + status = cf_write_psml_packets(&cfile, &print_args); + break; + case export_type_pdml: /* PDML */ + status = cf_write_pdml_packets(&cfile, &print_args); + break; + default: + return; + } + + switch (status) { + case CF_PRINT_OK: + break; + case CF_PRINT_OPEN_ERROR: + open_failure_alert_box(print_args.file, errno, TRUE); + break; + case CF_PRINT_WRITE_ERROR: + write_failure_alert_box(print_args.file, errno); + break; + } + /* Save the directory name for future file dialogs. */ + dirname = get_dirname(file_name); /* Overwrites cf_name */ + set_last_open_dir(dirname); + } +} + +void +win32_export_raw_file(HWND h_wnd) { + static OPENFILENAME ofn; + gchar file_name[MAX_PATH] = ""; + char *dirname; + const guint8 *data_p = NULL; + const char *file = NULL; + int fd; + + if (!cfile.finfo_selected) { + /* This shouldn't happen */ + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "No bytes were selected."); + return; + } + + ZeroMemory(&ofn, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = h_wnd; + ofn.hInstance = (HINSTANCE) GetWindowLong(h_wnd, GWL_HINSTANCE); + /* XXX - Grab the rest of the extension list from ethereal.nsi. */ + ofn.lpstrFilter = + "Raw data (*.bin, *.dat, *.raw)\0" "*.bin;*.dat;*.raw\0" + "All Files (*.*)\0" "*.*\0" + "\0"; + ofn.lpstrCustomFilter = NULL; + ofn.nMaxCustFilter = 0; + ofn.nFilterIndex = 1; + ofn.lpstrFile = file_name; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + if (prefs.gui_fileopen_style == FO_STYLE_SPECIFIED && prefs.gui_fileopen_dir[0] != '\0') { + ofn.lpstrInitialDir = prefs.gui_fileopen_dir; + } else { + ofn.lpstrInitialDir = NULL; + } + ofn.lpstrTitle = "Ethereal: Export Raw Data"; + ofn.Flags = OFN_ENABLESIZING | OFN_ENABLETEMPLATE | OFN_EXPLORER | + OFN_NOCHANGEDIR | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | + OFN_PATHMUSTEXIST | OFN_ENABLEHOOK; + ofn.lpstrDefExt = NULL; + ofn.lCustData = cfile.finfo_selected->length; + ofn.lpfnHook = export_raw_file_hook_proc; + ofn.lpTemplateName = "ETHEREAL_EXPORTRAWFILENAME_TEMPLATE"; + + /* + * XXX - The GTK+ code uses get_byte_view_data_and_length(). We just + * grab the info from cfile.finfo_selected. Which is more "correct"? + */ + + if (GetSaveFileName(&ofn)) { + + data_p = tvb_get_ptr(cfile.finfo_selected->ds_tvb, 0, -1) + + cfile.finfo_selected->start; + fd = open(file_name, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666); + if (fd == -1) { + open_failure_alert_box(file, errno, TRUE); + return; + } + if (write(fd, data_p, cfile.finfo_selected->length) < 0) { + write_failure_alert_box(file, errno); + close(fd); + return; + } + if (close(fd) < 0) { + write_failure_alert_box(file, errno); + return; + } + + /* Save the directory name for future file dialogs. */ + dirname = get_dirname(file_name); /* Overwrites cf_name */ + set_last_open_dir(dirname); + } +} + +void +win32_export_color_file(HWND h_wnd) { + static OPENFILENAME ofn; + gchar file_name[MAX_PATH] = ""; + char *dirname; + + ZeroMemory(&ofn, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = h_wnd; + ofn.hInstance = (HINSTANCE) GetWindowLong(h_wnd, GWL_HINSTANCE); + /* XXX - Grab the rest of the extension list from ethereal.nsi. */ + ofn.lpstrFilter = + "Text Files (*.txt)\0" "*.txt\0" + "All Files (*.*)\0" "*.*\0" + "\0"; + ofn.lpstrCustomFilter = NULL; + ofn.nMaxCustFilter = 0; + ofn.nFilterIndex = 2; + ofn.lpstrFile = file_name; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + ofn.lpstrInitialDir = NULL; + ofn.lpstrTitle = "Ethereal: Export Color Filters"; + ofn.Flags = OFN_ENABLESIZING | OFN_EXPLORER | + OFN_NOCHANGEDIR | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | + OFN_PATHMUSTEXIST | OFN_ENABLEHOOK; + ofn.lpstrDefExt = NULL; + ofn.lpfnHook = NULL; + ofn.lpTemplateName = NULL; + + filetype = cfile.cd_t; + + /* XXX - Support marked filters */ + if (GetSaveFileName(&ofn)) { + if (!color_filters_export(file_name, FALSE)) + return; + + /* Save the directory name for future file dialogs. */ + dirname = get_dirname(file_name); /* Overwrites cf_name */ + set_last_open_dir(dirname); + } +} + +void +win32_import_color_file(HWND h_wnd) { + static OPENFILENAME ofn; + gchar file_name[MAX_PATH] = ""; + char *dirname; + + ZeroMemory(&ofn, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = h_wnd; + ofn.hInstance = (HINSTANCE) GetWindowLong(h_wnd, GWL_HINSTANCE); + /* XXX - Grab the rest of the extension list from ethereal.nsi. */ + ofn.lpstrFilter = + "Text Files (*.txt)\0" "*.txt\0" + "All Files (*.*)\0" "*.*\0" + "\0"; + ofn.lpstrCustomFilter = NULL; + ofn.nMaxCustFilter = 0; + ofn.nFilterIndex = 2; + ofn.lpstrFile = file_name; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + ofn.lpstrInitialDir = NULL; + ofn.lpstrTitle = "Ethereal: Import Color Filters"; + ofn.Flags = OFN_ENABLESIZING | OFN_EXPLORER | + OFN_NOCHANGEDIR | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | + OFN_PATHMUSTEXIST | OFN_ENABLEHOOK; + ofn.lpstrDefExt = NULL; + ofn.lpfnHook = NULL; + ofn.lpTemplateName = NULL; + + /* XXX - Support marked filters */ + if (GetOpenFileName(&ofn)) { + if (!color_filters_import(file_name, NULL)) + return; + + /* Save the directory name for future file dialogs. */ + dirname = get_dirname(file_name); /* Overwrites cf_name */ + set_last_open_dir(dirname); + } +} + + +/* + * Private routines + */ +static void +format_handle_wm_initdialog(HWND dlg_hwnd, print_args_t *args) { + HWND cur_ctrl; + + /* Set the "Packet summary" box */ + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_SUMMARY_CB); + SendMessage(cur_ctrl, BM_SETCHECK, args->print_summary, 0); + + /* Set the "Packet details" box */ + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_DETAIL_CB); + SendMessage(cur_ctrl, BM_SETCHECK, args->print_dissections != print_dissections_none, 0); + + /* Set the "Packet details" combo */ + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_DETAIL_COMBO); + SendMessage(cur_ctrl, CB_ADDSTRING, 0, (LPARAM) (LPCTSTR) "All collapsed"); + SendMessage(cur_ctrl, CB_ADDSTRING, 0, (LPARAM) (LPCTSTR) "As displayed"); + SendMessage(cur_ctrl, CB_ADDSTRING, 0, (LPARAM) (LPCTSTR) "All expanded"); + + switch (args->print_dissections) { + case print_dissections_none: + case print_dissections_collapsed: + SendMessage(cur_ctrl, CB_SETCURSEL, 0, 0); + break; + case print_dissections_as_displayed: + SendMessage(cur_ctrl, CB_SETCURSEL, 1, 0); + break; + case print_dissections_expanded: + SendMessage(cur_ctrl, CB_SETCURSEL, 2, 0); + default: + g_assert_not_reached(); + } + + /* Set the "Packet bytes" box */ + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_BYTES_CB); + SendMessage(cur_ctrl, BM_SETCHECK, args->print_hex, 0); + + /* Set the "Each packet on a new page" box */ + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_NEW_PAGE_CB); + SendMessage(cur_ctrl, BM_SETCHECK, args->print_formfeed, 0); + + print_update_dynamic(dlg_hwnd, args); +} + +static void +print_update_dynamic(HWND dlg_hwnd, print_args_t *args) { + HWND cur_ctrl; + + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_SUMMARY_CB); + if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) + args->print_summary = TRUE; + else + args->print_summary = FALSE; + + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_DETAIL_CB); + if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) { + switch (SendMessage(cur_ctrl, CB_GETCURSEL, 0, 0)) { + case 0: + args->print_dissections = print_dissections_collapsed; + break; + case 1: + args->print_dissections = print_dissections_as_displayed; + break; + case 2: + args->print_dissections = print_dissections_expanded; + break; + default: + g_assert_not_reached(); + } + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_DETAIL_COMBO); + EnableWindow(cur_ctrl, TRUE); + } else { + args->print_dissections = print_dissections_none; + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_DETAIL_COMBO); + EnableWindow(cur_ctrl, FALSE); + } + + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_BYTES_CB); + if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) + args->print_hex = TRUE; + else + args->print_hex = FALSE; + + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_PKT_NEW_PAGE_CB); + if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) + args->print_formfeed = TRUE; + else + args->print_formfeed = FALSE; +} + + +/* + * Private routines + */ + +#define PREVIEW_STR_MAX 200 +#define PREVIEW_TIMEOUT_SECS 3 + + +/* If preview_file is NULL, disable the elements. If not, enable and + * show the preview info. */ +static gboolean +preview_set_filename(HWND of_hwnd, gchar *preview_file) { + HWND cur_ctrl; + int i; + gboolean enable = FALSE; + wtap *wth; + const struct wtap_pkthdr *phdr; + int err = 0; + gchar *err_info; + long data_offset; + gchar string_buff[PREVIEW_STR_MAX]; + guint packet = 0; + guint64 filesize; + time_t ti_time; + struct tm *ti_tm; + guint elapsed_time; + time_t time_preview; + time_t time_current; + double start_time = 0; + double stop_time = 0; + double cur_time; + gboolean is_breaked = FALSE; + + if (preview_file != NULL && strlen(preview_file) > 0) { + enable = TRUE; + } + + for (i = EWFD_PT_FILENAME; i <= EWFD_PTX_ELAPSED; i++) { + cur_ctrl = GetDlgItem(of_hwnd, i); + if (cur_ctrl) { + EnableWindow(cur_ctrl, enable); + } + } + + for (i = EWFD_PTX_FILENAME; i <= EWFD_PTX_ELAPSED; i++) { + cur_ctrl = GetDlgItem(of_hwnd, i); + if (cur_ctrl) { + SetWindowText(cur_ctrl, "-"); + } + } + + if (enable) { + cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_FILENAME); + SetWindowText(cur_ctrl, get_basename(preview_file)); + + cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_FORMAT); + wth = wtap_open_offline(preview_file, &err, &err_info, TRUE); + if (cur_ctrl && wth == NULL) { + if(err == WTAP_ERR_FILE_UNKNOWN_FORMAT) { + SetWindowText(cur_ctrl, "unknown file format"); + } else { + SetWindowText(cur_ctrl, "error opening file"); + } + return FALSE; + } + + /* size */ + filesize = wtap_file_size(wth, &err); + g_snprintf(string_buff, PREVIEW_STR_MAX, "%" PRIu64 " bytes", filesize); + cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_SIZE); + SetWindowText(cur_ctrl, string_buff); + + /* type */ + g_snprintf(string_buff, PREVIEW_STR_MAX, "%s", wtap_file_type_string(wtap_file_type(wth))); + cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_FORMAT); + SetWindowText(cur_ctrl, string_buff); + + time(&time_preview); + while ( (wtap_read(wth, &err, &err_info, &data_offset)) ) { + phdr = wtap_phdr(wth); + cur_time = nstime_to_sec( (const nstime_t *) &phdr->ts ); + if(packet == 0) { + start_time = cur_time; + stop_time = cur_time; + } + if (cur_time < start_time) { + start_time = cur_time; + } + if (cur_time > stop_time){ + stop_time = cur_time; + } + packet++; + if(packet%100) { + time(&time_current); + if(time_current-time_preview >= PREVIEW_TIMEOUT_SECS) { + is_breaked = TRUE; + break; + } + } + } + + if(err != 0) { + g_snprintf(string_buff, PREVIEW_STR_MAX, "error after reading %u packets", packet); + cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_PACKETS); + SetWindowText(cur_ctrl, string_buff); + wtap_close(wth); + return TRUE; + } + + /* packet count */ + if(is_breaked) { + g_snprintf(string_buff, PREVIEW_STR_MAX, "more than %u packets (preview timeout)", packet); + } else { + g_snprintf(string_buff, PREVIEW_STR_MAX, "%u", packet); + } + cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_PACKETS); + SetWindowText(cur_ctrl, string_buff); + + /* first packet */ + ti_time = (long)start_time; + ti_tm = localtime( &ti_time ); + g_snprintf(string_buff, PREVIEW_STR_MAX, + "%04d-%02d-%02d %02d:%02d:%02d", + ti_tm->tm_year + 1900, + ti_tm->tm_mon + 1, + ti_tm->tm_mday, + ti_tm->tm_hour, + ti_tm->tm_min, + ti_tm->tm_sec); + cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_FIRST_PKT); + SetWindowText(cur_ctrl, string_buff); + + /* elapsed time */ + elapsed_time = (unsigned int)(stop_time-start_time); + if(elapsed_time/86400) { + g_snprintf(string_buff, PREVIEW_STR_MAX, "%02u days %02u:%02u:%02u", + elapsed_time/86400, elapsed_time%86400/3600, elapsed_time%3600/60, elapsed_time%60); + } else { + g_snprintf(string_buff, PREVIEW_STR_MAX, "%02u:%02u:%02u", + elapsed_time%86400/3600, elapsed_time%3600/60, elapsed_time%60); + } + if(is_breaked) { + g_snprintf(string_buff, PREVIEW_STR_MAX, "unknown"); + } + cur_ctrl = GetDlgItem(of_hwnd, EWFD_PTX_ELAPSED); + SetWindowText(cur_ctrl, string_buff); + + wtap_close(wth); + } + + return TRUE; + +} + +// XXX - Copied from "filter-util.c" in the ethereal-win32 branch +/* XXX - The only reason for the "filter_text" parameter is to be able to feed + * in the "real" filter string in the case of a CBN_SELCHANGE notification message. + */ +void +filter_tb_syntax_check(HWND hwnd, gchar *filter_text) { + gchar *strval = NULL; + gint len; + dfilter_t *dfp; + + /* If filter_text is non-NULL, use it. Otherwise, grab the text from + * the window */ + if (filter_text) { + strval = g_strdup(filter_text); + len = lstrlen(filter_text); + } else { + len = GetWindowTextLength(hwnd); + if (len > 0) { + len++; + strval = g_malloc(len); + GetWindowText(hwnd, strval, len); + } + } + + if (len == 0) { + /* Default window background */ + SendMessage(hwnd, EM_SETBKGNDCOLOR, (WPARAM) 1, COLOR_WINDOW); + return; + } else if (dfilter_compile(strval, &dfp)) { /* colorize filter string entry */ + if (dfp != NULL) + dfilter_free(dfp); + /* Valid (light green) */ + SendMessage(hwnd, EM_SETBKGNDCOLOR, 0, 0x00afffaf); + } else { + /* Invalid (light red) */ + SendMessage(hwnd, EM_SETBKGNDCOLOR, 0, 0x00afafff); + } + + if (strval) g_free(strval); +} + + +static UINT CALLBACK +open_file_hook_proc(HWND of_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) { + HWND cur_ctrl, parent; + OFNOTIFY *notify = (OFNOTIFY *) l_param; + gchar sel_name[MAX_PATH]; + + switch(msg) { + case WM_INITDIALOG: + /* XXX - Retain the filter text, and fill it in. */ + + /* Fill in our resolution values */ + cur_ctrl = GetDlgItem(of_hwnd, EWFD_MAC_NR_CB); + SendMessage(cur_ctrl, BM_SETCHECK, g_resolv_flags & RESOLV_MAC, 0); + cur_ctrl = GetDlgItem(of_hwnd, EWFD_NET_NR_CB); + SendMessage(cur_ctrl, BM_SETCHECK, g_resolv_flags & RESOLV_NETWORK, 0); + cur_ctrl = GetDlgItem(of_hwnd, EWFD_TRANS_NR_CB); + SendMessage(cur_ctrl, BM_SETCHECK, g_resolv_flags & RESOLV_TRANSPORT, 0); + + preview_set_filename(of_hwnd, NULL); + break; + case WM_NOTIFY: + switch (notify->hdr.code) { + case CDN_FILEOK: + /* XXX - Fetch the read filter */ + /* Fetch our resolution values */ + g_resolv_flags = prefs.name_resolve & RESOLV_CONCURRENT; + cur_ctrl = GetDlgItem(of_hwnd, EWFD_MAC_NR_CB); + if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) + g_resolv_flags |= RESOLV_MAC; + cur_ctrl = GetDlgItem(of_hwnd, EWFD_NET_NR_CB); + if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) + g_resolv_flags |= RESOLV_NETWORK; + cur_ctrl = GetDlgItem(of_hwnd, EWFD_TRANS_NR_CB); + if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) + g_resolv_flags |= RESOLV_TRANSPORT; + break; + case CDN_SELCHANGE: + /* This _almost_ works correctly. We need to handle directory + selections, etc. */ + parent = GetParent(of_hwnd); + CommDlg_OpenSave_GetSpec(parent, sel_name, MAX_PATH); + preview_set_filename(of_hwnd, sel_name); + break; + default: + break; + } + break; + case WM_COMMAND: + cur_ctrl = (HWND) l_param; + switch(w_param) { + case (EN_UPDATE << 16) | EWFD_FILTER_EDIT: + filter_tb_syntax_check(cur_ctrl, NULL); + break; + default: + break; + } + break; + default: + break; + } + return 0; +} + +/* XXX - Copied verbatim from gtk/file_dlg.c. Perhaps it + * should be in wiretap instead? + */ + +static gboolean +can_save_with_wiretap(int ft) +{ + /* To save a file with Wiretap, Wiretap has to handle that format, + and its code to handle that format must be able to write a file + with this file's encapsulation type. */ + return wtap_dump_can_open(ft) && wtap_dump_can_write_encap(ft, cfile.lnk_t); +} + +/* Generate a list of the file types we can save this file as. + + "filetype" is the type it has now. + + "encap" is the encapsulation for its packets (which could be + "unknown" or "per-packet"). + + "filtered" is TRUE if we're to save only the packets that passed + the display filter (in which case we have to save it using Wiretap) + and FALSE if we're to save the entire file (in which case, if we're + saving it in the type it has already, we can just copy it). + + The same applies for sel_curr, sel_all, sel_m_only, sel_m_range and sel_man_range +*/ + +static void +build_file_format_list(HWND sf_hwnd) { + HWND format_cb; + int ft; + guint index; + guint item_to_select; + + /* Default to the first supported file type, if the file's current + type isn't supported. */ + item_to_select = 0; + + format_cb = GetDlgItem(sf_hwnd, EWFD_FILE_TYPE_COMBO); + SendMessage(format_cb, CB_RESETCONTENT, 0, 0); + + /* Check all file types. */ + index = 0; + for (ft = 0; ft < WTAP_NUM_FILE_TYPES; ft++) { + if (!packet_range_process_all(&range) || ft != cfile.cd_t) { + /* not all unfiltered packets or a different file type. We have to use Wiretap. */ + if (!can_save_with_wiretap(ft)) + continue; /* We can't. */ + } + + /* OK, we can write it out in this type. */ + SendMessage(format_cb, CB_ADDSTRING, 0, (LPARAM) (LPCTSTR) wtap_file_type_string(ft)); + SendMessage(format_cb, CB_SETITEMDATA, (LPARAM) index, (WPARAM) ft); + if (ft == filetype) { + /* Default to the same format as the file, if it's supported. */ + item_to_select = index; + } + index++; + } + + SendMessage(format_cb, CB_SETCURSEL, (WPARAM) item_to_select, 0); +} + +#define RANGE_TEXT_MAX 128 +static UINT CALLBACK +save_as_file_hook_proc(HWND sf_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) { + HWND cur_ctrl; + OFNOTIFY *notify = (OFNOTIFY *) l_param; + int new_filetype, index; + + switch(msg) { + case WM_INITDIALOG: + g_sf_hwnd = sf_hwnd; + + /* Default to saving all packets, in the file's current format. */ + filetype = cfile.cd_t; + + /* init the packet range */ + packet_range_init(&range); + + /* Fill in the file format list */ + build_file_format_list(sf_hwnd); + + range_handle_wm_initdialog(sf_hwnd, &range); + + break; + case WM_COMMAND: + cur_ctrl = (HWND) l_param; + + switch (w_param) { + case (CBN_SELCHANGE << 16) | EWFD_FILE_TYPE_COMBO: + index = SendMessage(cur_ctrl, CB_GETCURSEL, 0, 0); + if (index != CB_ERR) { + new_filetype = SendMessage(cur_ctrl, CB_GETITEMDATA, (WPARAM) index, 0); + if (new_filetype != CB_ERR) { + if (filetype != new_filetype) { + if (can_save_with_wiretap(new_filetype)) { + cur_ctrl = GetDlgItem(sf_hwnd, EWFD_CAPTURED_BTN); + EnableWindow(cur_ctrl, TRUE); + cur_ctrl = GetDlgItem(sf_hwnd, EWFD_DISPLAYED_BTN); + EnableWindow(cur_ctrl, TRUE); + } else { + cur_ctrl = GetDlgItem(sf_hwnd, EWFD_CAPTURED_BTN); + SendMessage(cur_ctrl, BM_SETCHECK, 0, 0); + EnableWindow(cur_ctrl, FALSE); + cur_ctrl = GetDlgItem(sf_hwnd, EWFD_DISPLAYED_BTN); + EnableWindow(cur_ctrl, FALSE); + } + filetype = new_filetype; + } + } + } + break; + default: + range_handle_wm_command(sf_hwnd, cur_ctrl, w_param, &range); + break; + } + break; + default: + break; + } + return 0; +} + + + +/* For each range static control, fill in its value and enable/disable it. */ +static void +range_update_dynamics(HWND dlg_hwnd, packet_range_t *range) { + HWND cur_ctrl; + gboolean filtered_active = FALSE; + gchar static_val[100]; + gint selected_num; + + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_DISPLAYED_BTN); + if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) + filtered_active = TRUE; + + /* RANGE_SELECT_ALL */ + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_ALL_PKTS_CAP); + EnableWindow(cur_ctrl, !filtered_active); + g_snprintf(static_val, sizeof(static_val), "%u", cfile.count); + SetWindowText(cur_ctrl, static_val); + + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_ALL_PKTS_DISP); + EnableWindow(cur_ctrl, filtered_active); + g_snprintf(static_val, sizeof(static_val), "%u", range->displayed_cnt); + SetWindowText(cur_ctrl, static_val); + + /* RANGE_SELECT_CURR */ + selected_num = (cfile.current_frame) ? cfile.current_frame->num : 0; + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_SEL_PKT_CAP); + EnableWindow(cur_ctrl, selected_num && !filtered_active); + g_snprintf(static_val, sizeof(static_val), "%u", selected_num ? 1 : 0); + SetWindowText(cur_ctrl, static_val); + + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_SEL_PKT_DISP); + EnableWindow(cur_ctrl, selected_num && filtered_active); + g_snprintf(static_val, sizeof(static_val), "%u", selected_num ? 1 : 0); + SetWindowText(cur_ctrl, static_val); + + /* RANGE_SELECT_MARKED */ + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_MARKED_BTN); + EnableWindow(cur_ctrl, cfile.marked_count); + + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_MARKED_CAP); + EnableWindow(cur_ctrl, cfile.marked_count && !filtered_active); + g_snprintf(static_val, sizeof(static_val), "%u", cfile.marked_count); + SetWindowText(cur_ctrl, static_val); + + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_MARKED_DISP); + EnableWindow(cur_ctrl, cfile.marked_count && filtered_active); + g_snprintf(static_val, sizeof(static_val), "%u", range->displayed_marked_cnt); + SetWindowText(cur_ctrl, static_val); + + /* RANGE_SELECT_MARKED_RANGE */ + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_FIRST_LAST_BTN); + EnableWindow(cur_ctrl, range->mark_range_cnt); + + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_FIRST_LAST_CAP); + EnableWindow(cur_ctrl, range->mark_range_cnt && !filtered_active); + g_snprintf(static_val, sizeof(static_val), "%u", range->mark_range_cnt); + SetWindowText(cur_ctrl, static_val); + + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_FIRST_LAST_DISP); + EnableWindow(cur_ctrl, range->displayed_mark_range_cnt && filtered_active); + g_snprintf(static_val, sizeof(static_val), "%u", range->displayed_mark_range_cnt); + SetWindowText(cur_ctrl, static_val); + + /* RANGE_SELECT_USER */ + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_CAP); + EnableWindow(cur_ctrl, !filtered_active); + g_snprintf(static_val, sizeof(static_val), "%u", range->user_range_cnt); + SetWindowText(cur_ctrl, static_val); + + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_DISP); + EnableWindow(cur_ctrl, filtered_active); + g_snprintf(static_val, sizeof(static_val), "%u", range->displayed_user_range_cnt); + SetWindowText(cur_ctrl, static_val); +} + +static void +range_handle_wm_initdialog(HWND dlg_hwnd, packet_range_t *range) { + HWND cur_ctrl; + + /* Set the appropriate captured/displayed radio */ + if (range->process_filtered) + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_DISPLAYED_BTN); + else + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_CAPTURED_BTN); + SendMessage(cur_ctrl, BM_SETCHECK, TRUE, 0); + + /* dynamic values in the range frame */ + range_update_dynamics(dlg_hwnd, range); + + /* Set the appropriate range radio */ + switch(range->process) { + case(range_process_all): + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_ALL_PKTS_BTN); + break; + case(range_process_selected): + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_SEL_PKT_BTN); + break; + case(range_process_marked): + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_MARKED_BTN); + break; + case(range_process_marked_range): + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_FIRST_LAST_BTN); + break; + case(range_process_user_range): + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_BTN); + break; + default: + g_assert_not_reached(); + } + SendMessage(cur_ctrl, BM_SETCHECK, TRUE, 0); +} + +static void +range_handle_wm_command(HWND dlg_hwnd, HWND ctrl, WPARAM w_param, packet_range_t *range) { + HWND cur_ctrl; + gchar range_text[RANGE_TEXT_MAX]; + + switch(w_param) { + case (BN_CLICKED << 16) | EWFD_CAPTURED_BTN: + case (BN_CLICKED << 16) | EWFD_DISPLAYED_BTN: + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_CAPTURED_BTN); + if (SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) + range->process_filtered = FALSE; + else + range->process_filtered = TRUE; + range_update_dynamics(dlg_hwnd, range); + break; + case (BN_CLICKED << 16) | EWFD_ALL_PKTS_BTN: + if (SendMessage(ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) { + range->process = range_process_all; + range_update_dynamics(dlg_hwnd, range); + } + break; + case (BN_CLICKED << 16) | EWFD_SEL_PKT_BTN: + if (SendMessage(ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) { + range->process = range_process_selected; + range_update_dynamics(dlg_hwnd, range); + } + break; + case (BN_CLICKED << 16) | EWFD_MARKED_BTN: + if (SendMessage(ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) { + range->process = range_process_marked; + range_update_dynamics(dlg_hwnd, range); + } + break; + case (BN_CLICKED << 16) | EWFD_FIRST_LAST_BTN: + if (SendMessage(ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) { + range->process = range_process_marked_range; + range_update_dynamics(dlg_hwnd, range); + } + break; + case (BN_CLICKED << 16) | EWFD_RANGE_BTN: + if (SendMessage(ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) { + range->process = range_process_user_range; + range_update_dynamics(dlg_hwnd, range); + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_EDIT); + SetFocus(cur_ctrl); + } + break; + case (EN_SETFOCUS << 16) | EWFD_RANGE_EDIT: + cur_ctrl = GetDlgItem(dlg_hwnd, EWFD_RANGE_BTN); + SendMessage(cur_ctrl, BM_CLICK, 0, 0); + break; + case (EN_CHANGE << 16) | EWFD_RANGE_EDIT: + SendMessage(ctrl, WM_GETTEXT, (WPARAM) RANGE_TEXT_MAX, (LPARAM) range_text); + packet_range_convert_str(range, range_text); + range_update_dynamics(dlg_hwnd, range); + break; + } +} + +static UINT CALLBACK +merge_file_hook_proc(HWND mf_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) { + HWND cur_ctrl, parent; + OFNOTIFY *notify = (OFNOTIFY *) l_param; + gchar sel_name[MAX_PATH]; + + switch(msg) { + case WM_INITDIALOG: + /* XXX - Retain the filter text, and fill it in. */ + + /* Append by default */ + cur_ctrl = GetDlgItem(mf_hwnd, EWFD_MERGE_PREPEND_BTN); + SendMessage(cur_ctrl, BM_SETCHECK, TRUE, 0); + merge_action = merge_append; + + preview_set_filename(mf_hwnd, NULL); + break; + case WM_NOTIFY: + switch (notify->hdr.code) { + case CDN_FILEOK: + /* XXX - Fetch the read filter */ + + cur_ctrl = GetDlgItem(mf_hwnd, EWFD_MERGE_CHRONO_BTN); + if(SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) { + merge_action = merge_chrono; + } else { + cur_ctrl = GetDlgItem(mf_hwnd, EWFD_MERGE_PREPEND_BTN); + if(SendMessage(cur_ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED) { + merge_action = merge_prepend; + } + } + + break; + case CDN_SELCHANGE: + /* This _almost_ works correctly. We need to handle directory + selections, etc. */ + parent = GetParent(mf_hwnd); + CommDlg_OpenSave_GetSpec(parent, sel_name, MAX_PATH); + preview_set_filename(mf_hwnd, sel_name); + break; + default: + break; + } + break; + case WM_COMMAND: + cur_ctrl = (HWND) l_param; + switch(w_param) { + case (EN_UPDATE << 16) | EWFD_FILTER_EDIT: + filter_tb_syntax_check(cur_ctrl, NULL); + break; + default: + break; + } + break; + default: + break; + } + return 0; +} + + +static UINT CALLBACK +export_file_hook_proc(HWND ef_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) { + HWND cur_ctrl; + OFNOTIFY *notify = (OFNOTIFY *) l_param; + gboolean pkt_fmt_enable; + int i, index; + + switch(msg) { + case WM_INITDIALOG: + /* init the printing range */ + packet_range_init(&print_args.range); + range_handle_wm_initdialog(ef_hwnd, &print_args.range); + format_handle_wm_initdialog(ef_hwnd, &print_args); + + break; + case WM_COMMAND: + cur_ctrl = (HWND) l_param; + switch (w_param) { +// case (CBN_SELCHANGE << 16) | EWFD_FILE_TYPE_COMBO: +// break; + default: + range_handle_wm_command(ef_hwnd, cur_ctrl, w_param, &print_args.range); + print_update_dynamic(ef_hwnd, &print_args); + break; + } + break; + case WM_NOTIFY: + switch (notify->hdr.code) { + case CDN_FILEOK: + break; + case CDN_TYPECHANGE: + index = notify->lpOFN->nFilterIndex; + + if (index == 2) /* PostScript */ + print_args.format = PR_FMT_TEXT; + else + print_args.format = PR_FMT_PS; + if (index == 3 || index == 4) + pkt_fmt_enable = FALSE; + else + pkt_fmt_enable = TRUE; + for (i = EWFD_PKT_FORMAT_GB; i <= EWFD_PKT_NEW_PAGE_CB; i++) { + cur_ctrl = GetDlgItem(ef_hwnd, i); + EnableWindow(cur_ctrl, pkt_fmt_enable); + } + break; + default: + break; + } + break; + default: + break; + } + return 0; +} + +static UINT CALLBACK +export_raw_file_hook_proc(HWND ef_hwnd, UINT msg, WPARAM w_param, LPARAM l_param) { + HWND cur_ctrl; + OPENFILENAME *ofnp = (OPENFILENAME *) l_param; + gchar raw_msg[100]; + + switch(msg) { + case WM_INITDIALOG: + g_snprintf(raw_msg, sizeof(raw_msg), "%d byte%s of raw binary data will be written", + ofnp->lCustData, plurality(ofnp->lCustData, "", "s")); + cur_ctrl = GetDlgItem(ef_hwnd, EWFD_EXPORTRAW_ST); + SetWindowText(cur_ctrl, raw_msg); + break; + default: + break; + } + return 0; +} diff --git a/gtk/win32-file-dlg.h b/gtk/win32-file-dlg.h new file mode 100755 index 0000000000..d5a35ea092 --- /dev/null +++ b/gtk/win32-file-dlg.h @@ -0,0 +1,133 @@ +#ifndef __WIN32_FILE_DLG_H__ +#define __WIN32_FILE_DLG_H__ + +typedef enum { + export_type_text = 1, + export_type_ps, + export_type_csv, + export_type_psml, + export_type_pdml +} export_type_e; + +/** Open the "Open" dialog box. + * + * @param h_wnd HWND of the parent window. + */ +gboolean win32_open_file (HWND h_wnd); + +/** Open the "Save As" dialog box. + * + * @param h_wnd HWND of the parent window. + * @param action_after_save The action to take, when save completed + * @param action_after_save_data Data for action_after_save + */ +void win32_save_as_file(HWND h_wnd, action_after_save_e action_after_save, gpointer action_after_save_data); + +/** Open the "Merge" dialog box. + * + * @param h_wnd HWND of the parent window. + */ +void win32_merge_file (HWND h_wnd); + +/** Open the "Export" dialog box. + * + * @param h_wnd HWND of the parent window. + */ +void win32_export_file (HWND h_wnd, export_type_e export_type); + +/** Open the "Export raw bytes" dialog box. + * + * @param h_wnd HWND of the parent window. + */ +void win32_export_raw_file (HWND h_wnd); + +/** Open the "Export Color Filters" dialog box + * + * @param h_wnd HWND of the parent window + */ +void win32_export_color_file(HWND h_wnd); + +/** Open the "Import Color Filters" dialog box + * + * @param h_wnd HWND of the parent window + */ +void win32_import_color_file(HWND h_wnd); + +/** Given a print_args_t struct, update a set of print/export format controls + * accordingly. + * + * @param dlg_hwnd HWND of the dialog in question. + * @args Pointer to a print args struct. + */ +/* XXX - This should be moved to win32-print.c, maybe? */ +void print_update_dynamic(HWND dlg_hwnd, print_args_t *args); + +void file_set_save_marked_sensitive(); + +/* Open dialog defines */ +#define EWFD_FILTER_BTN 1000 +#define EWFD_FILTER_EDIT 1001 + +#define EWFD_MAC_NR_CB 1002 +#define EWFD_NET_NR_CB 1003 +#define EWFD_TRANS_NR_CB 1004 + +/* Note: The preview title (PT) and text (PTX) MUST have sequential IDs; + they're used in a for loop. EWFD_PT_FILENAME MUST be first, and + EWFD_PTX_ELAPSED MUST be last. (so why don't we just use an enum? */ +#define EWFD_PT_FILENAME 1005 +#define EWFD_PT_FORMAT 1006 +#define EWFD_PT_SIZE 1007 +#define EWFD_PT_PACKETS 1008 +#define EWFD_PT_FIRST_PKT 1009 +#define EWFD_PT_ELAPSED 1010 + +#define EWFD_PTX_FILENAME 1011 +#define EWFD_PTX_FORMAT 1012 +#define EWFD_PTX_SIZE 1013 +#define EWFD_PTX_PACKETS 1014 +#define EWFD_PTX_FIRST_PKT 1015 +#define EWFD_PTX_ELAPSED 1016 + + +/* Save dialog defines */ +#define EWFD_CAPTURED_BTN 1000 +#define EWFD_DISPLAYED_BTN 1001 +#define EWFD_ALL_PKTS_BTN 1002 +#define EWFD_SEL_PKT_BTN 1003 +#define EWFD_MARKED_BTN 1004 +#define EWFD_FIRST_LAST_BTN 1005 +#define EWFD_RANGE_BTN 1006 +#define EWFD_RANGE_EDIT 1007 +#define EWFD_FILE_TYPE_COMBO 1008 + +#define EWFD_ALL_PKTS_CAP 1009 +#define EWFD_SEL_PKT_CAP 1010 +#define EWFD_MARKED_CAP 1011 +#define EWFD_FIRST_LAST_CAP 1012 +#define EWFD_RANGE_CAP 1013 + +#define EWFD_ALL_PKTS_DISP 1014 +#define EWFD_SEL_PKT_DISP 1015 +#define EWFD_MARKED_DISP 1016 +#define EWFD_FIRST_LAST_DISP 1017 +#define EWFD_RANGE_DISP 1018 + +/* Export raw dialog defines. */ +#define EWFD_EXPORTRAW_ST 1000 + +/* Merge dialog defines. Overlays Open dialog defines above. */ +#define EWFD_MERGE_PREPEND_BTN 1050 +#define EWFD_MERGE_CHRONO_BTN 1051 +#define EWFD_MERGE_APPEND_BTN 1052 + +/* Export dialog defines. Overlays Save dialog defines above. */ +/* These MUST be contiguous */ +#define EWFD_PKT_FORMAT_GB 1050 +#define EWFD_PKT_SUMMARY_CB 1051 +#define EWFD_PKT_DETAIL_CB 1052 +#define EWFD_PKT_DETAIL_COMBO 1053 +#define EWFD_PKT_BYTES_CB 1054 +#define EWFD_PKT_NEW_PAGE_CB 1055 + +#endif /* win32-file-dlg.h */ diff --git a/image/ethereal.rc.in b/image/ethereal.rc.in index 3542775fb5..65b0cc616f 100644 --- a/image/ethereal.rc.in +++ b/image/ethereal.rc.in @@ -1,5 +1,7 @@ #include "winver.h" +#include "image/win32-file-dlg.rc" + ETHEREAL_ICON ICON "ethereal.ico" VS_VERSION_INFO VERSIONINFO diff --git a/image/win32-file-dlg.rc b/image/win32-file-dlg.rc new file mode 100755 index 0000000000..02babb0152 --- /dev/null +++ b/image/win32-file-dlg.rc @@ -0,0 +1,135 @@ +#include +#include "richedit.h" +#include "gtk/win32-file-dlg.h" + +ETHEREAL_OPENFILENAME_TEMPLATE DIALOG 0, 0, 368, 94 +STYLE WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | DS_3DLOOK | DS_CONTROL +FONT 8, "MS Shell Dlg" +{ + // Filter button/entry + PUSHBUTTON "Filter:", EWFD_FILTER_BTN, 7, 4, 35, 14 + CONTROL "", EWFD_FILTER_EDIT, RICHEDIT_CLASS, ES_AUTOHSCROLL, 49, 5, 101, 12, WS_EX_CLIENTEDGE + + CHECKBOX "MAC name resolution", EWFD_MAC_NR_CB, 7, 32, 100, 8, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + CHECKBOX "Network name resolution", EWFD_NET_NR_CB, 7, 47, 100, 8, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + CHECKBOX "Transport name resolution", EWFD_TRANS_NR_CB, 7, 62, 100, 8, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + + LTEXT "Filename:", EWFD_PT_FILENAME, 164, 4, 40, 8 + LTEXT "-", EWFD_PTX_FILENAME, 211, 4, 150, 8 + LTEXT "Format:", EWFD_PT_FORMAT, 164, 19, 40, 8 + LTEXT "-", EWFD_PTX_FORMAT, 211, 19, 150, 8 + LTEXT "Size:", EWFD_PT_SIZE, 164, 34, 40, 8 + LTEXT "-", EWFD_PTX_SIZE, 211, 34, 150, 8, SS_RIGHT + LTEXT "Packets:", EWFD_PT_PACKETS, 164, 49, 40, 8 + LTEXT "-", EWFD_PTX_PACKETS, 211, 49, 150, 8, SS_RIGHT + LTEXT "First Packet:", EWFD_PT_FIRST_PKT, 164, 64, 40, 8 + LTEXT "-", EWFD_PTX_FIRST_PKT, 211, 64, 150, 8, SS_RIGHT + LTEXT "Elapsed Time:", EWFD_PT_ELAPSED, 164, 79, 40, 8 + LTEXT "-", EWFD_PTX_ELAPSED, 211, 79, 150, 8 +} + +ETHEREAL_SAVEFILENAME_TEMPLATE DIALOG 0, 0, 368, 116 +STYLE WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | DS_3DLOOK | DS_CONTROL +FONT 8, "MS Shell Dlg" +{ + // XXX - We need to come up with something less confusing than separate + // "Save as type" (which is built-in) and "File format" combos. + LTEXT "File format:", -1, 5, 3, 35, 8 + COMBOBOX EWFD_FILE_TYPE_COMBO, 54, 2, 155, 51, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + + GROUPBOX "Packet Range", -1, 5, 21, 210, 90 + + CONTROL "Captured", EWFD_CAPTURED_BTN, "Button", BS_AUTORADIOBUTTON | WS_GROUP, 110, 32, 45, 10 + CONTROL "Displayed", EWFD_DISPLAYED_BTN, "Button", BS_AUTORADIOBUTTON, 160, 32, 47, 10 + + CONTROL "All packets", EWFD_ALL_PKTS_BTN, "Button", BS_AUTORADIOBUTTON | WS_GROUP, 16, 44, 51, 10 + CONTROL "Selected packet", EWFD_SEL_PKT_BTN, "Button", BS_AUTORADIOBUTTON, 16, 56, 68, 10 + CONTROL "Marked packets", EWFD_MARKED_BTN, "Button", BS_AUTORADIOBUTTON, 16, 68, 67, 10 + CONTROL "First to last marked", EWFD_FIRST_LAST_BTN, "Button", BS_AUTORADIOBUTTON, 16, 80, 75, 10 + CONTROL "Range:", EWFD_RANGE_BTN, "Button", BS_AUTORADIOBUTTON, 16, 92, 35, 10 + EDITTEXT EWFD_RANGE_EDIT, 53, 91, 30, 12, ES_AUTOHSCROLL + + LTEXT "0", EWFD_ALL_PKTS_CAP, 110, 45, 39, 8, SS_RIGHT + LTEXT "0", EWFD_SEL_PKT_CAP, 110, 57, 39, 8, SS_RIGHT + LTEXT "0", EWFD_MARKED_CAP, 110, 69, 39, 8, SS_RIGHT + LTEXT "0", EWFD_FIRST_LAST_CAP, 110, 81, 39, 8, SS_RIGHT + LTEXT "0", EWFD_RANGE_CAP, 110, 93, 39, 8, SS_RIGHT + + LTEXT "0", EWFD_ALL_PKTS_DISP, 160, 45, 41, 8, SS_RIGHT + LTEXT "0", EWFD_SEL_PKT_DISP, 160, 57, 41, 8, SS_RIGHT + LTEXT "0", EWFD_MARKED_DISP, 160, 69, 41, 8, SS_RIGHT + LTEXT "0", EWFD_FIRST_LAST_DISP, 160, 81, 41, 8, SS_RIGHT + LTEXT "0", EWFD_RANGE_DISP, 160, 93, 41, 8, SS_RIGHT +} + +ETHEREAL_MERGEFILENAME_TEMPLATE DIALOG 0, 0, 368, 94 +STYLE WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | DS_3DLOOK | DS_CONTROL +FONT 8, "MS Shell Dlg" +{ + // Filter button/entry + PUSHBUTTON "Filter:", EWFD_FILTER_BTN, 7, 4, 35, 14 + CONTROL "", EWFD_FILTER_EDIT, RICHEDIT_CLASS, ES_AUTOHSCROLL, 49, 5, 101, 12, WS_EX_CLIENTEDGE + + CONTROL "Prepend packets to existing file", EWFD_MERGE_PREPEND_BTN, "Button", BS_AUTORADIOBUTTON | WS_GROUP, 7, 32, 120, 8 + CONTROL "Merge packets chronologically", EWFD_MERGE_CHRONO_BTN, "Button", BS_AUTORADIOBUTTON, 7, 47, 120, 8 + CONTROL "Append packets to existing file", EWFD_MERGE_APPEND_BTN, "Button", BS_AUTORADIOBUTTON, 7, 62, 120, 8 + + LTEXT "Filename:", EWFD_PT_FILENAME, 164, 4, 40, 8 + LTEXT "-", EWFD_PTX_FILENAME, 211, 4, 150, 8 + LTEXT "Format:", EWFD_PT_FORMAT, 164, 19, 40, 8 + LTEXT "-", EWFD_PTX_FORMAT, 211, 19, 150, 8 + LTEXT "Size:", EWFD_PT_SIZE, 164, 34, 40, 8 + LTEXT "-", EWFD_PTX_SIZE, 211, 34, 150, 8, SS_RIGHT + LTEXT "Packets:", EWFD_PT_PACKETS, 164, 49, 40, 8 + LTEXT "-", EWFD_PTX_PACKETS, 211, 49, 150, 8, SS_RIGHT + LTEXT "First Packet:", EWFD_PT_FIRST_PKT, 164, 64, 40, 8 + LTEXT "-", EWFD_PTX_FIRST_PKT, 211, 64, 150, 8, SS_RIGHT + LTEXT "Elapsed Time:", EWFD_PT_ELAPSED, 164, 79, 40, 8 + LTEXT "-", EWFD_PTX_ELAPSED, 211, 79, 150, 8 +} + +// XXX - The width value appears to have no effect, at least on Windows XP. +ETHEREAL_EXPORTFILENAME_TEMPLATE DIALOG 0, 0, 5000, 97 +STYLE WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | DS_3DLOOK | DS_CONTROL +FONT 8, "MS Shell Dlg" +{ + GROUPBOX "Packet Range", -1, 5, 2, 210, 90 + + CONTROL "Captured", EWFD_CAPTURED_BTN, "Button", BS_AUTORADIOBUTTON | WS_GROUP, 110, 13, 45, 10 + CONTROL "Displayed", EWFD_DISPLAYED_BTN, "Button", BS_AUTORADIOBUTTON, 160, 13, 47, 10 + + CONTROL "All packets", EWFD_ALL_PKTS_BTN, "Button", BS_AUTORADIOBUTTON | WS_GROUP, 16, 25, 51, 10 + CONTROL "Selected packet", EWFD_SEL_PKT_BTN, "Button", BS_AUTORADIOBUTTON, 16, 37, 68, 10 + CONTROL "Marked packets", EWFD_MARKED_BTN, "Button", BS_AUTORADIOBUTTON, 16, 49, 67, 10 + CONTROL "First to last marked", EWFD_FIRST_LAST_BTN, "Button", BS_AUTORADIOBUTTON, 16, 61, 75, 10 + CONTROL "Range:", EWFD_RANGE_BTN, "Button", BS_AUTORADIOBUTTON, 16, 73, 35, 10 + EDITTEXT EWFD_RANGE_EDIT, 53, 72, 30, 12, ES_AUTOHSCROLL + + LTEXT "0", EWFD_ALL_PKTS_CAP, 110, 26, 39, 8, SS_RIGHT + LTEXT "0", EWFD_SEL_PKT_CAP, 110, 38, 39, 8, SS_RIGHT + LTEXT "0", EWFD_MARKED_CAP, 110, 50, 39, 8, SS_RIGHT + LTEXT "0", EWFD_FIRST_LAST_CAP, 110, 62, 39, 8, SS_RIGHT + LTEXT "0", EWFD_RANGE_CAP, 110, 74, 39, 8, SS_RIGHT + + LTEXT "0", EWFD_ALL_PKTS_DISP, 160, 26, 41, 8, SS_RIGHT + LTEXT "0", EWFD_SEL_PKT_DISP, 160, 38, 41, 8, SS_RIGHT + LTEXT "0", EWFD_MARKED_DISP, 160, 50, 41, 8, SS_RIGHT + LTEXT "0", EWFD_FIRST_LAST_DISP, 160, 62, 41, 8, SS_RIGHT + LTEXT "0", EWFD_RANGE_DISP, 160, 74, 41, 8, SS_RIGHT + + GROUPBOX "Packet Format", EWFD_PKT_FORMAT_GB, 224, 2, 119, 90 + CONTROL "Packet summary line", EWFD_PKT_SUMMARY_CB, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 235, 15, 84, 10 + CONTROL "Packet details:", EWFD_PKT_DETAIL_CB, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 235, 27, 95, 10 + COMBOBOX EWFD_PKT_DETAIL_COMBO, 247, 39, 74, 45, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "Packet Bytes", EWFD_PKT_BYTES_CB, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 235, 56, 80, 10 + CONTROL "Each packet on a new page", EWFD_PKT_NEW_PAGE_CB, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 235, 70, 106, 10 + +} + + +ETHEREAL_EXPORTRAWFILENAME_TEMPLATE DIALOG 0, 0, 200, 18 +STYLE WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | DS_3DLOOK | DS_CONTROL +FONT 8, "MS Shell Dlg" +{ + LTEXT "-", EWFD_EXPORTRAW_ST, 5, 5, 180, 8 +} -- cgit v1.2.3