2 * Dialog boxes for printing and exporting to text files
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 #include <epan/prefs.h>
32 #include <epan/epan_dissect.h>
33 #include <epan/filesystem.h>
34 #include <epan/print.h>
36 #include "ui/alert_box.h"
37 #include "ui/simple_dialog.h"
39 #include <wsutil/file_util.h>
41 #include "ui/gtk/gtkglobals.h"
42 #include "ui/gtk/keys.h"
43 #include "ui/gtk/gui_utils.h"
44 #include "ui/gtk/dlg_utils.h"
45 #include "ui/gtk/file_dlg.h"
46 #include "ui/gtk/main.h"
47 #include "ui/gtk/stock_icons.h"
48 #include "ui/gtk/range_utils.h"
49 #include "ui/gtk/help_dlg.h"
52 #include <gdk/gdkwin32.h>
54 #include "ui/win32/file_dlg_win32.h"
55 #include "ui/win32/print_win32.h"
56 #include "wsutil/tempfile.h"
59 /* dialog output action */
61 output_action_print
, /* print text to printer */
62 output_action_export_text
, /* export to plain text */
63 output_action_export_ps
, /* export to postscript */
64 output_action_export_psml
, /* export to packet summary markup language */
65 output_action_export_pdml
, /* export to packet data markup language */
66 output_action_export_csv
, /* export to csv file */
67 output_action_export_carrays
/* export to C array file */
71 /* On Win32, a GUI application apparently can't use "popen()" (it
72 "returns an invalid file handle, if used in a Windows program,
73 that will cause the program to hang indefinitely"), so we can't
74 use a pipe to a print command to print to a printer.
76 Eventually, we should try to use the native Win32 printing API
77 for this (and also use various UNIX printing APIs, when present?).
81 open_print_dialog(const char *title
, output_action_e action
, print_args_t
*args
);
82 static void print_cmd_toggle_dest(GtkWidget
*widget
, gpointer data
);
83 static void print_cmd_toggle_detail(GtkWidget
*widget
, gpointer data
);
84 static void print_ok_cb(GtkWidget
*ok_bt
, gpointer parent_w
);
85 static void print_destroy_cb(GtkWidget
*win
, gpointer user_data
);
89 #define PRINT_ARGS_KEY "printer_args"
91 #define PRINT_PS_RB_KEY "printer_ps_radio_button"
92 #define PRINT_PDML_RB_KEY "printer_pdml_radio_button"
93 #define PRINT_PSML_RB_KEY "printer_psml_radio_button"
94 #define PRINT_CSV_RB_KEY "printer_csv_radio_button"
95 #define PRINT_CARRAYS_RB_KEY "printer_carrays_radio_button"
96 #define PRINT_DEST_CB_KEY "printer_destination_check_button"
98 #define PRINT_SUMMARY_CB_KEY "printer_summary_check_button"
99 #define PRINT_COL_HEADINGS_CB_KEY "printer_include_column_headings_button"
100 #define PRINT_DETAILS_CB_KEY "printer_details_check_button"
101 #define PRINT_COLLAPSE_ALL_RB_KEY "printer_collapse_all_radio_button"
102 #define PRINT_AS_DISPLAYED_RB_KEY "printer_as_displayed_radio_button"
103 #define PRINT_EXPAND_ALL_RB_KEY "printer_expand_all_radio_button"
104 #define PRINT_HEX_CB_KEY "printer_hex_check_button"
105 #define PRINT_FORMFEED_CB_KEY "printer_formfeed_check_button"
107 #define PRINT_BT_KEY "printer_button"
109 #define PRINT_TE_PTR_KEY "printer_file_te_ptr"
113 * Keep a static pointer to the current "Print" window, if any, so that if
114 * somebody tries to do "File:Print" while there's already a "Print" window
115 * up, we just pop up the existing one, rather than creating a new one.
117 static GtkWidget
*print_win
= NULL
;
119 static print_args_t print_args
;
121 static gboolean print_prefs_init
= FALSE
;
125 file_print_cmd(gboolean print_selected
)
127 print_args_t
*args
= &print_args
;
129 if (print_win
!= NULL
) {
130 /* There's already a "Print" dialog box; reactivate it. */
131 reactivate_window(print_win
);
135 /* get settings from preferences (and other initial values) only once */
136 if(print_prefs_init
== FALSE
) {
137 print_prefs_init
= TRUE
;
138 args
->format
= (print_format_e
)prefs
.pr_format
;
139 args
->to_file
= prefs
.pr_dest
;
140 args
->file
= g_strdup(prefs
.pr_file
);
141 args
->cmd
= g_strdup(prefs
.pr_cmd
);
142 args
->print_summary
= TRUE
;
143 args
->print_col_headings
= TRUE
;
144 args
->print_dissections
= print_dissections_as_displayed
;
145 args
->print_hex
= FALSE
;
146 args
->print_formfeed
= FALSE
;
149 /* init the printing range */
150 packet_range_init(&args
->range
, &cfile
);
151 args
->range
.process_filtered
= TRUE
;
154 args
->range
.process
= range_process_selected
;
157 print_win
= open_print_dialog("Wireshark: Print", output_action_print
, args
);
158 g_signal_connect(print_win
, "destroy", G_CALLBACK(print_destroy_cb
), &print_win
);
162 file_print_cmd_cb(GtkWidget
*widget _U_
, gpointer data _U_
)
164 file_print_cmd(FALSE
);
168 file_print_selected_cmd_cb(GtkWidget
*widget _U_
, gpointer data _U_
)
170 file_print_cmd(TRUE
);
174 * Keep a static pointer to the current "Export text" window, if any, so that if
175 * somebody tries to do "File:Export to text" while there's already a "Export text" window
176 * up, we just pop up the existing one, rather than creating a new one.
178 static GtkWidget
*export_text_win
= NULL
;
180 static print_args_t export_text_args
;
182 static gboolean export_text_prefs_init
= FALSE
;
187 export_text_cmd_cb(GtkWidget
*widget _U_
, gpointer data _U_
)
189 win32_export_file(GDK_WINDOW_HWND(gtk_widget_get_window(top_level
)), &cfile
, export_type_text
);
194 export_text_cmd_cb(GtkWidget
*widget _U_
, gpointer data _U_
)
196 print_args_t
*args
= &export_text_args
;
198 if (export_text_win
!= NULL
) {
199 /* There's already a "Export text" dialog box; reactivate it. */
200 reactivate_window(export_text_win
);
204 /* get settings from preferences (and other initial values) only once */
205 if(export_text_prefs_init
== FALSE
) {
206 export_text_prefs_init
= TRUE
;
207 args
->format
= PR_FMT_TEXT
;
208 args
->to_file
= TRUE
;
209 args
->file
= g_strdup("");
210 args
->cmd
= g_strdup("");
211 args
->print_summary
= TRUE
;
212 args
->print_col_headings
= TRUE
;
213 args
->print_dissections
= print_dissections_as_displayed
;
214 args
->print_hex
= FALSE
;
215 args
->print_formfeed
= FALSE
;
218 /* init the printing range */
219 packet_range_init(&args
->range
, &cfile
);
220 args
->range
.process_filtered
= TRUE
;
222 export_text_win
= open_print_dialog("Wireshark: Export as \"Plain Text\" File", output_action_export_text
, args
);
223 g_signal_connect(export_text_win
, "destroy", G_CALLBACK(print_destroy_cb
), &export_text_win
);
229 * Keep a static pointer to the current "Export ps" window, if any, so that if
230 * somebody tries to do "File:Export to ps" while there's already a "Export ps" window
231 * up, we just pop up the existing one, rather than creating a new one.
233 static GtkWidget
*export_ps_win
= NULL
;
235 static print_args_t export_ps_args
;
237 static gboolean export_ps_prefs_init
= FALSE
;
242 export_ps_cmd_cb(GtkWidget
*widget _U_
, gpointer data _U_
)
244 win32_export_file(GDK_WINDOW_HWND(gtk_widget_get_window(top_level
)), &cfile
, export_type_ps
);
249 export_ps_cmd_cb(GtkWidget
*widget _U_
, gpointer data _U_
)
251 print_args_t
*args
= &export_ps_args
;
253 if (export_ps_win
!= NULL
) {
254 /* There's already a "Export ps" dialog box; reactivate it. */
255 reactivate_window(export_ps_win
);
259 /* get settings from preferences (and other initial values) only once */
260 if(export_ps_prefs_init
== FALSE
) {
261 export_ps_prefs_init
= TRUE
;
262 args
->format
= PR_FMT_PS
;
263 args
->to_file
= TRUE
;
264 args
->file
= g_strdup("");
265 args
->cmd
= g_strdup("");
266 args
->print_summary
= TRUE
;
267 args
->print_col_headings
= TRUE
;
268 args
->print_dissections
= print_dissections_as_displayed
;
269 args
->print_hex
= FALSE
;
270 args
->print_formfeed
= FALSE
;
273 /* init the printing range */
274 packet_range_init(&args
->range
, &cfile
);
275 args
->range
.process_filtered
= TRUE
;
277 export_ps_win
= open_print_dialog("Wireshark: Export as \"PostScript\" file", output_action_export_ps
, args
);
278 g_signal_connect(export_ps_win
, "destroy", G_CALLBACK(print_destroy_cb
), &export_ps_win
);
284 * Keep a static pointer to the current "Export psml" window, if any, so that if
285 * somebody tries to do "File:Export to psml" while there's already a "Export psml" window
286 * up, we just pop up the existing one, rather than creating a new one.
288 static GtkWidget
*export_psml_win
= NULL
;
290 static print_args_t export_psml_args
;
292 static gboolean export_psml_prefs_init
= FALSE
;
297 export_psml_cmd_cb(GtkWidget
*widget _U_
, gpointer data _U_
)
299 win32_export_file(GDK_WINDOW_HWND(gtk_widget_get_window(top_level
)), &cfile
, export_type_psml
);
304 export_psml_cmd_cb(GtkWidget
*widget _U_
, gpointer data _U_
)
306 print_args_t
*args
= &export_psml_args
;
308 if (export_psml_win
!= NULL
) {
309 /* There's already a "Export psml" dialog box; reactivate it. */
310 reactivate_window(export_psml_win
);
314 /* get settings from preferences (and other initial values) only once */
315 if(export_psml_prefs_init
== FALSE
) {
316 export_psml_prefs_init
= TRUE
;
317 args
->format
= PR_FMT_TEXT
; /* XXX */
318 args
->to_file
= TRUE
;
319 args
->file
= g_strdup("");
320 args
->cmd
= g_strdup("");
321 args
->print_summary
= TRUE
;
322 args
->print_col_headings
= TRUE
;
323 args
->print_dissections
= print_dissections_as_displayed
;
324 args
->print_hex
= FALSE
;
325 args
->print_formfeed
= FALSE
;
328 /* init the printing range */
329 packet_range_init(&args
->range
, &cfile
);
330 args
->range
.process_filtered
= TRUE
;
332 export_psml_win
= open_print_dialog("Wireshark: Export as \"PSML\" file", output_action_export_psml
, args
);
333 g_signal_connect(export_psml_win
, "destroy", G_CALLBACK(print_destroy_cb
), &export_psml_win
);
338 * Keep a static pointer to the current "Export pdml" window, if any, so that if
339 * somebody tries to do "File:Export to pdml" while there's already a "Export pdml" window
340 * up, we just pop up the existing one, rather than creating a new one.
342 static GtkWidget
*export_pdml_win
= NULL
;
344 static print_args_t export_pdml_args
;
346 static gboolean export_pdml_prefs_init
= FALSE
;
351 export_pdml_cmd_cb(GtkWidget
*widget _U_
, gpointer data _U_
)
353 win32_export_file(GDK_WINDOW_HWND(gtk_widget_get_window(top_level
)), &cfile
, export_type_pdml
);
358 export_pdml_cmd_cb(GtkWidget
*widget _U_
, gpointer data _U_
)
360 print_args_t
*args
= &export_pdml_args
;
362 if (export_pdml_win
!= NULL
) {
363 /* There's already a "Export pdml" dialog box; reactivate it. */
364 reactivate_window(export_pdml_win
);
368 /* get settings from preferences (and other initial values) only once */
369 if(export_pdml_prefs_init
== FALSE
) {
370 export_pdml_prefs_init
= TRUE
;
371 args
->format
= PR_FMT_TEXT
; /* XXX */
372 args
->to_file
= TRUE
;
373 args
->file
= g_strdup("");
374 args
->cmd
= g_strdup("");
375 args
->print_summary
= TRUE
;
376 args
->print_col_headings
= TRUE
;
377 args
->print_dissections
= print_dissections_as_displayed
;
378 args
->print_hex
= FALSE
;
379 args
->print_formfeed
= FALSE
;
382 /* init the printing range */
383 packet_range_init(&args
->range
, &cfile
);
384 args
->range
.process_filtered
= TRUE
;
386 export_pdml_win
= open_print_dialog("Wireshark: Export as \"PDML\" file", output_action_export_pdml
, args
);
387 g_signal_connect(export_pdml_win
, "destroy", G_CALLBACK(print_destroy_cb
), &export_pdml_win
);
392 * Keep a static pointer to the current "Export csv" window, if any, so that if
393 * somebody tries to do "File:Export to CSV" while there's already a "Export csv" window
394 * up, we just pop up the existing one, rather than creating a new one.
396 static GtkWidget
*export_csv_win
= NULL
;
398 static print_args_t export_csv_args
;
400 static gboolean export_csv_prefs_init
= FALSE
;
404 export_csv_cmd_cb(GtkWidget
*widget _U_
, gpointer data _U_
)
406 win32_export_file(GDK_WINDOW_HWND(gtk_widget_get_window(top_level
)), &cfile
, export_type_csv
);
411 export_csv_cmd_cb(GtkWidget
*widget _U_
, gpointer data _U_
)
413 print_args_t
*args
= &export_csv_args
;
415 if (export_csv_win
!= NULL
) {
416 /* There's already a "Export csv" dialog box; reactivate it. */
417 reactivate_window(export_csv_win
);
421 /* get settings from preferences (and other initial values) only once */
422 if(export_csv_prefs_init
== FALSE
) {
423 export_csv_prefs_init
= TRUE
;
424 args
->format
= PR_FMT_TEXT
; /* XXX */
425 args
->to_file
= TRUE
;
426 args
->file
= g_strdup("");
427 args
->cmd
= g_strdup("");
428 args
->print_summary
= FALSE
;
429 args
->print_col_headings
= FALSE
;
430 args
->print_dissections
= print_dissections_none
;
431 args
->print_hex
= FALSE
;
432 args
->print_formfeed
= FALSE
;
435 /* init the printing range */
436 packet_range_init(&args
->range
, &cfile
);
437 args
->range
.process_filtered
= TRUE
;
439 export_csv_win
= open_print_dialog("Wireshark: Export as \"Comma Separated Values\" File", output_action_export_csv
, args
);
440 g_signal_connect(export_csv_win
, "destroy", G_CALLBACK(print_destroy_cb
), &export_csv_win
);
445 * Keep a static pointer to the current "Export carrays" window, if any, so that if
446 * somebody tries to do "File:Export to carrays" while there's already a "Export carrays" window
447 * up, we just pop up the existing one, rather than creating a new one.
449 static GtkWidget
*export_carrays_win
= NULL
;
451 static print_args_t export_carrays_args
;
453 static gboolean export_carrays_prefs_init
= FALSE
;
457 export_carrays_cmd_cb(GtkWidget
*widget _U_
, gpointer data _U_
)
459 win32_export_file(GDK_WINDOW_HWND(gtk_widget_get_window(top_level
)), &cfile
, export_type_carrays
);
464 export_carrays_cmd_cb(GtkWidget
*widget _U_
, gpointer data _U_
)
466 print_args_t
*args
= &export_carrays_args
;
468 if (export_carrays_win
!= NULL
) {
469 /* There's already a "Export carrays" dialog box; reactivate it. */
470 reactivate_window(export_carrays_win
);
474 /* get settings from preferences (and other initial values) only once */
475 if(export_carrays_prefs_init
== FALSE
) {
476 export_carrays_prefs_init
= TRUE
;
477 args
->format
= PR_FMT_TEXT
;
478 args
->to_file
= TRUE
;
479 args
->file
= g_strdup("");
480 args
->cmd
= g_strdup("");
481 args
->print_summary
= FALSE
;
482 args
->print_col_headings
= FALSE
;
483 args
->print_dissections
= print_dissections_none
;
484 args
->print_hex
= FALSE
;
485 args
->print_formfeed
= FALSE
;
488 /* init the printing range */
489 packet_range_init(&args
->range
, &cfile
);
490 args
->range
.process_filtered
= TRUE
;
492 export_carrays_win
= open_print_dialog("Wireshark: Export as \"C Arrays\" File",
493 output_action_export_carrays
, args
);
494 g_signal_connect(export_carrays_win
, "destroy", G_CALLBACK(print_destroy_cb
), &export_carrays_win
);
499 print_browse_file_cb(GtkWidget
*file_bt
, GtkWidget
*file_te
)
501 file_selection_browse(file_bt
, file_te
, "Wireshark: Print to File",
502 FILE_SELECTION_WRITE_BROWSE
);
507 /* Open the print dialog */
509 open_print_dialog(const char *title
, output_action_e action
, print_args_t
*args
)
514 GtkWidget
*printer_fr
, *printer_vb
, *export_format_lb
;
515 GtkWidget
*text_rb
, *ps_rb
, *pdml_rb
, *psml_rb
, *csv_rb
, *carrays_rb
;
516 GtkWidget
*printer_grid
, *dest_cb
;
518 GtkWidget
*cmd_lb
, *cmd_te
;
520 GtkWidget
*file_bt
, *file_te
;
522 GtkWidget
*range_fr
, *range_grid
;
524 GtkWidget
*packet_hb
;
526 GtkWidget
*format_fr
, *format_vb
;
527 GtkWidget
*summary_cb
;
528 GtkWidget
*col_headings_cb
;
530 GtkWidget
*details_cb
;
531 GtkWidget
*details_hb
, *details_vb
;
532 GtkWidget
*collapse_all_rb
, *as_displayed_rb
, *expand_all_rb
;
534 GtkWidget
*sep
, *formfeed_cb
;
536 GtkWidget
*bbox
, *ok_bt
, *cancel_bt
, *help_bt
;
539 main_win
= dlg_window_new(title
);
541 /* Vertical enclosing container for each row of widgets */
542 main_vb
= ws_gtk_box_new(GTK_ORIENTATION_VERTICAL
, 5, FALSE
);
543 gtk_container_set_border_width(GTK_CONTAINER(main_vb
), 5);
544 gtk_container_add(GTK_CONTAINER(main_win
), main_vb
);
545 gtk_widget_show(main_vb
);
547 /*****************************************************/
549 /*** printer frame ***/
550 printer_fr
= gtk_frame_new(action
== output_action_print
? "Printer" : "Export to file:");
551 gtk_box_pack_start(GTK_BOX(main_vb
), printer_fr
, TRUE
, TRUE
, 0);
552 gtk_widget_show(printer_fr
);
554 printer_vb
= ws_gtk_box_new(GTK_ORIENTATION_VERTICAL
, 5, FALSE
);
555 gtk_container_set_border_width(GTK_CONTAINER(printer_vb
), 5);
556 gtk_container_add(GTK_CONTAINER(printer_fr
), printer_vb
);
557 gtk_widget_show(printer_vb
);
559 /* "Plain text" / "Postscript" / "PDML", ... radio buttons */
560 text_rb
= gtk_radio_button_new_with_mnemonic_from_widget(NULL
, "Plain _text");
561 if (args
->format
== PR_FMT_TEXT
)
562 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(text_rb
), TRUE
);
563 gtk_widget_set_tooltip_text(text_rb
, "Print output in ascii \"plain text\" format. If you're unsure, use this format.");
564 gtk_box_pack_start(GTK_BOX(printer_vb
), text_rb
, FALSE
, FALSE
, 0);
565 if(action
== output_action_print
)
566 gtk_widget_show(text_rb
);
568 ps_rb
= gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(text_rb
), "_PostScript");
569 if (args
->format
== PR_FMT_PS
)
570 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ps_rb
), TRUE
);
571 gtk_widget_set_tooltip_text(ps_rb
, "Print output in \"postscript\" format, for postscript capable printers or print servers.");
572 gtk_box_pack_start(GTK_BOX(printer_vb
), ps_rb
, FALSE
, FALSE
, 0);
573 if(action
== output_action_print
)
574 gtk_widget_show(ps_rb
);
576 pdml_rb
= gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(text_rb
), "PDM_L (XML: Packet Details Markup Language)");
577 if (action
== output_action_export_pdml
)
578 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pdml_rb
), TRUE
);
579 gtk_widget_set_tooltip_text(pdml_rb
,
580 "Print output in \"PDML\" (Packet Details Markup Language), "
581 "an XML based packet data interchange format. "
582 "Usually used in combination with the \"Output to file\" option to export packet data into an XML file.");
583 gtk_box_pack_start(GTK_BOX(printer_vb
), pdml_rb
, FALSE
, FALSE
, 0);
584 /* gtk_widget_show(pdml_rb); */
586 psml_rb
= gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(text_rb
), "PSML (XML: Packet Summary Markup Language)");
587 if (action
== output_action_export_psml
)
588 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(psml_rb
), TRUE
);
589 gtk_widget_set_tooltip_text(psml_rb
,
590 "Print output in \"PSML\" (Packet Summary Markup Language), "
591 "an XML based packet summary interchange format. "
592 "Usually used in combination with the \"Output to file\" option to export packet data into an XML file.");
593 gtk_box_pack_start(GTK_BOX(printer_vb
), psml_rb
, FALSE
, FALSE
, 0);
594 /* gtk_widget_show(psml_rb); */
596 csv_rb
= gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(text_rb
), "_CSV");
597 if (action
== output_action_export_csv
)
598 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(csv_rb
), TRUE
);
599 gtk_widget_set_tooltip_text(csv_rb
,
600 "Print output in \"Comma Separated Values\" (CSV) format, "
601 "a text format compatible with OpenOffice and Excel. "
602 "One row for each packet, with its timestamp and size.");
603 gtk_box_pack_start(GTK_BOX(printer_vb
), csv_rb
, FALSE
, FALSE
, 0);
604 /* gtk_widget_show(csv_rb); */
606 carrays_rb
= gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(text_rb
), "C Arrays");
607 if (action
== output_action_export_carrays
)
608 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(carrays_rb
), TRUE
);
609 gtk_widget_set_tooltip_text(carrays_rb
,
610 "Print output in C Arrays format, "
611 "a text file suitable for use in C/C++ programs. "
612 "One char[] for each packet.");
613 gtk_box_pack_start(GTK_BOX(printer_vb
), carrays_rb
, FALSE
, FALSE
, 0);
614 /* gtk_widget_show(carrays_rb); */
617 printer_grid
= ws_gtk_grid_new();
618 gtk_box_pack_start(GTK_BOX(printer_vb
), printer_grid
, FALSE
, FALSE
, 0);
620 ws_gtk_grid_set_row_spacing(GTK_GRID(printer_grid
), 5);
621 ws_gtk_grid_set_column_spacing(GTK_GRID(printer_grid
), 5);
622 gtk_widget_show(printer_grid
);
625 /* Output to file button */
626 dest_cb
= gtk_check_button_new_with_mnemonic("Output to _file:");
628 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dest_cb
), TRUE
);
629 gtk_widget_set_tooltip_text(dest_cb
, "Output to file instead of printer");
630 ws_gtk_grid_attach(GTK_GRID(printer_grid
), dest_cb
, 0, 0, 1, 1);
631 if(action
== output_action_print
)
632 gtk_widget_show(dest_cb
);
634 /* File text entry */
635 file_te
= gtk_entry_new();
636 g_object_set_data(G_OBJECT(dest_cb
), PRINT_FILE_TE_KEY
, file_te
);
637 gtk_widget_set_tooltip_text(file_te
, "Enter Output filename");
638 gtk_entry_set_text(GTK_ENTRY(file_te
), args
->file
);
639 ws_gtk_grid_attach_extended(GTK_GRID(printer_grid
), file_te
, 1, 0, 1, 1, (GtkAttachOptions
)(GTK_EXPAND
|GTK_FILL
), (GtkAttachOptions
)0, 0, 0);
640 gtk_widget_set_sensitive(file_te
, args
->to_file
);
641 gtk_widget_show(file_te
);
643 gtk_widget_grab_focus(file_te
);
645 /* "Browse" button */
646 file_bt
= gtk_button_new_from_stock(WIRESHARK_STOCK_BROWSE
);
647 g_object_set_data(G_OBJECT(dest_cb
), PRINT_FILE_BT_KEY
, file_bt
);
648 g_object_set_data(G_OBJECT(file_bt
), PRINT_TE_PTR_KEY
, file_te
);
649 gtk_widget_set_tooltip_text(file_bt
, "Browse output filename in filesystem");
650 ws_gtk_grid_attach(GTK_GRID(printer_grid
), file_bt
, 2, 0, 1, 1);
651 gtk_widget_set_sensitive(file_bt
, args
->to_file
);
652 gtk_widget_show(file_bt
);
654 /* Command label and text entry */
656 cmd_lb
= gtk_label_new("Print command:");
657 g_object_set_data(G_OBJECT(dest_cb
), PRINT_CMD_LB_KEY
, cmd_lb
);
658 gtk_misc_set_alignment(GTK_MISC(cmd_lb
), 1.0f
, 0.5f
);
659 ws_gtk_grid_attach(GTK_GRID(printer_grid
), cmd_lb
, 0, 1, 1, 1);
660 gtk_widget_set_sensitive(cmd_lb
, !args
->to_file
);
661 if(action
== output_action_print
)
662 gtk_widget_show(cmd_lb
);
664 cmd_te
= gtk_entry_new();
665 g_object_set_data(G_OBJECT(dest_cb
), PRINT_CMD_TE_KEY
, cmd_te
);
666 gtk_widget_set_tooltip_text(cmd_te
, "Enter print command");
667 gtk_entry_set_text(GTK_ENTRY(cmd_te
), args
->cmd
);
668 ws_gtk_grid_attach(GTK_GRID(printer_grid
), cmd_te
, 1, 1, 1, 1);
669 gtk_widget_set_sensitive(cmd_te
, !args
->to_file
);
670 if(action
== output_action_print
)
671 gtk_widget_show(cmd_te
);
674 g_signal_connect(dest_cb
, "toggled", G_CALLBACK(print_cmd_toggle_dest
), NULL
);
675 g_signal_connect(file_bt
, "clicked", G_CALLBACK(print_browse_file_cb
), file_te
);
677 if(action
== output_action_export_ps
) {
678 export_format_lb
= gtk_label_new("(PostScript files can be easily converted to PDF files using ghostscript's ps2pdf)");
679 gtk_box_pack_start(GTK_BOX(printer_vb
), export_format_lb
, FALSE
, FALSE
, 0);
680 gtk_widget_show(export_format_lb
);
683 /*****************************************************/
685 /*** hor box for range and format frames ***/
686 packet_hb
= ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 5, FALSE
);
687 gtk_box_pack_start(GTK_BOX(main_vb
), packet_hb
, TRUE
, TRUE
, 0);
688 gtk_widget_show(packet_hb
);
690 /*** packet range frame ***/
691 range_fr
= gtk_frame_new("Packet Range");
692 gtk_box_pack_start(GTK_BOX(packet_hb
), range_fr
, FALSE
, FALSE
, 0);
693 gtk_widget_show(range_fr
);
695 range_grid
= range_new(&args
->range
, FALSE
);
696 gtk_container_add(GTK_CONTAINER(range_fr
), range_grid
);
697 gtk_widget_show(range_grid
);
699 /*****************************************************/
701 /*** packet format frame ***/
702 format_fr
= gtk_frame_new("Packet Format");
703 gtk_box_pack_start(GTK_BOX(packet_hb
), format_fr
, TRUE
, TRUE
, 0);
704 if( action
== output_action_print
||
705 action
== output_action_export_text
||
706 action
== output_action_export_ps
)
707 gtk_widget_show(format_fr
);
708 format_vb
= ws_gtk_box_new(GTK_ORIENTATION_VERTICAL
, 5, FALSE
);
709 gtk_container_set_border_width(GTK_CONTAINER(format_vb
), 5);
710 gtk_container_add(GTK_CONTAINER(format_fr
), format_vb
);
711 gtk_widget_show(format_vb
);
713 /* "Print summary line" check button */
714 summary_cb
= gtk_check_button_new_with_mnemonic("Packet summary line");
715 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(summary_cb
), args
->print_summary
);
716 g_signal_connect(summary_cb
, "clicked", G_CALLBACK(print_cmd_toggle_detail
), main_win
);
717 gtk_widget_set_tooltip_text(summary_cb
, "Output of a packet summary line, like in the packet list");
718 gtk_box_pack_start(GTK_BOX(format_vb
), summary_cb
, TRUE
, TRUE
, 0);
719 gtk_widget_show(summary_cb
);
721 /* "Include column headings" check button */
722 col_headings_cb
= gtk_check_button_new_with_mnemonic("Include column headings");
723 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(col_headings_cb
), args
->print_col_headings
);
724 gtk_widget_set_sensitive(col_headings_cb
, args
->print_summary
);
725 g_signal_connect(col_headings_cb
, "clicked", G_CALLBACK(print_cmd_toggle_detail
), main_win
);
726 gtk_widget_set_tooltip_text(col_headings_cb
, "Include column headings when printing the packet summary line");
727 gtk_box_pack_start(GTK_BOX(format_vb
), col_headings_cb
, TRUE
, TRUE
, 0);
728 gtk_widget_show(col_headings_cb
);
730 /* "Details" check button */
731 details_cb
= gtk_check_button_new_with_mnemonic("Packet details:");
732 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(details_cb
), args
->print_dissections
!= print_dissections_none
);
733 g_signal_connect(details_cb
, "clicked", G_CALLBACK(print_cmd_toggle_detail
), main_win
);
734 gtk_widget_set_tooltip_text(details_cb
, "Output format of the selected packet details (protocol tree).");
735 gtk_box_pack_start(GTK_BOX(format_vb
), details_cb
, TRUE
, TRUE
, 0);
736 gtk_widget_show(details_cb
);
738 /*** packet details ***/
739 details_hb
= ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 6, FALSE
);
740 gtk_container_set_border_width(GTK_CONTAINER(details_hb
), 0);
741 gtk_box_pack_start(GTK_BOX(format_vb
), details_hb
, TRUE
, TRUE
, 0);
742 gtk_widget_show(details_hb
);
744 details_vb
= ws_gtk_box_new(GTK_ORIENTATION_VERTICAL
, 6, FALSE
);
745 gtk_container_set_border_width(GTK_CONTAINER(details_vb
), 0);
746 gtk_box_pack_start(GTK_BOX(details_hb
), details_vb
, FALSE
, FALSE
, 10);
747 gtk_widget_show(details_vb
);
749 details_vb
= ws_gtk_box_new(GTK_ORIENTATION_VERTICAL
, 6, FALSE
);
750 gtk_container_set_border_width(GTK_CONTAINER(details_vb
), 0);
751 gtk_box_pack_start(GTK_BOX(details_hb
), details_vb
, FALSE
, FALSE
, 0);
752 gtk_widget_show(details_vb
);
754 /* "All collapsed"/"As displayed"/"All Expanded" radio buttons */
755 collapse_all_rb
= gtk_radio_button_new_with_mnemonic_from_widget(NULL
, "All co_llapsed");
756 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(collapse_all_rb
), args
->print_dissections
== print_dissections_collapsed
);
757 gtk_widget_set_sensitive(collapse_all_rb
, args
->print_dissections
!= print_dissections_none
);
758 gtk_widget_set_tooltip_text(collapse_all_rb
, "Output of the packet details tree \"collapsed\"");
759 gtk_box_pack_start(GTK_BOX(details_vb
), collapse_all_rb
, TRUE
, TRUE
, 0);
760 gtk_widget_show(collapse_all_rb
);
762 as_displayed_rb
= gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(collapse_all_rb
), "As displa_yed");
763 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(as_displayed_rb
), args
->print_dissections
== print_dissections_as_displayed
);
764 gtk_widget_set_sensitive(as_displayed_rb
, args
->print_dissections
!= print_dissections_none
);
765 gtk_widget_set_tooltip_text(as_displayed_rb
, "Output of the packet details tree \"as displayed\"");
766 gtk_box_pack_start(GTK_BOX(details_vb
), as_displayed_rb
, TRUE
, TRUE
, 0);
767 gtk_widget_show(as_displayed_rb
);
769 expand_all_rb
= gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(collapse_all_rb
), "All e_xpanded");
770 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(expand_all_rb
), args
->print_dissections
== print_dissections_expanded
);
771 gtk_widget_set_sensitive(expand_all_rb
, args
->print_dissections
!= print_dissections_none
);
772 gtk_widget_set_tooltip_text(expand_all_rb
, "Output of the packet details tree \"expanded\"");
773 gtk_box_pack_start(GTK_BOX(details_vb
), expand_all_rb
, TRUE
, TRUE
, 0);
774 gtk_widget_show(expand_all_rb
);
776 /* "Print hex" check button. */
777 hex_cb
= gtk_check_button_new_with_mnemonic("Packet bytes");
778 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(hex_cb
), args
->print_hex
);
779 g_signal_connect(hex_cb
, "clicked", G_CALLBACK(print_cmd_toggle_detail
), main_win
);
780 gtk_widget_set_tooltip_text(hex_cb
, "Add a hexdump of the packet data");
781 gtk_box_pack_start(GTK_BOX(format_vb
), hex_cb
, TRUE
, TRUE
, 0);
782 gtk_widget_show(hex_cb
);
785 sep
= gtk_separator_new(GTK_ORIENTATION_HORIZONTAL
);
786 gtk_box_pack_start(GTK_BOX(format_vb
), sep
, TRUE
, TRUE
, 0);
787 gtk_widget_show(sep
);
789 /* "Each packet on a new page" check button. */
790 formfeed_cb
= gtk_check_button_new_with_mnemonic("Each packet on a new page");
791 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(formfeed_cb
), args
->print_formfeed
);
792 gtk_widget_set_tooltip_text (formfeed_cb
, "When checked, a new page will be used for each packet. "
793 "This is done by adding a formfeed (or similar) between the packet outputs.");
794 gtk_box_pack_start(GTK_BOX(format_vb
), formfeed_cb
, TRUE
, TRUE
, 0);
795 gtk_widget_show(formfeed_cb
);
798 g_object_set_data(G_OBJECT(main_win
), PRINT_ARGS_KEY
, args
);
799 g_object_set_data(G_OBJECT(main_win
), PRINT_SUMMARY_CB_KEY
, summary_cb
);
800 g_object_set_data(G_OBJECT(main_win
), PRINT_COL_HEADINGS_CB_KEY
, col_headings_cb
);
801 g_object_set_data(G_OBJECT(main_win
), PRINT_DETAILS_CB_KEY
, details_cb
);
802 g_object_set_data(G_OBJECT(main_win
), PRINT_COLLAPSE_ALL_RB_KEY
, collapse_all_rb
);
803 g_object_set_data(G_OBJECT(main_win
), PRINT_AS_DISPLAYED_RB_KEY
, as_displayed_rb
);
804 g_object_set_data(G_OBJECT(main_win
), PRINT_EXPAND_ALL_RB_KEY
, expand_all_rb
);
805 g_object_set_data(G_OBJECT(main_win
), PRINT_HEX_CB_KEY
, hex_cb
);
807 /*****************************************************/
811 bbox
= dlg_button_row_new(action
== output_action_print
? GTK_STOCK_PRINT
: GTK_STOCK_OK
, GTK_STOCK_CANCEL
, GTK_STOCK_HELP
, NULL
);
812 gtk_box_pack_start(GTK_BOX(main_vb
), bbox
, FALSE
, FALSE
, 0);
813 gtk_widget_show(bbox
);
815 ok_bt
= (GtkWidget
*)g_object_get_data(G_OBJECT(bbox
), action
== output_action_print
? GTK_STOCK_PRINT
: GTK_STOCK_OK
);
817 g_object_set_data(G_OBJECT(main_win
), PRINT_BT_KEY
, ok_bt
);
819 g_object_set_data(G_OBJECT(ok_bt
), PRINT_PS_RB_KEY
, ps_rb
);
820 g_object_set_data(G_OBJECT(ok_bt
), PRINT_PDML_RB_KEY
, pdml_rb
);
821 g_object_set_data(G_OBJECT(ok_bt
), PRINT_PSML_RB_KEY
, psml_rb
);
822 g_object_set_data(G_OBJECT(ok_bt
), PRINT_CSV_RB_KEY
, csv_rb
);
823 g_object_set_data(G_OBJECT(ok_bt
), PRINT_CARRAYS_RB_KEY
, carrays_rb
);
824 g_object_set_data(G_OBJECT(ok_bt
), PRINT_DEST_CB_KEY
, dest_cb
);
826 g_object_set_data(G_OBJECT(ok_bt
), PRINT_CMD_TE_KEY
, cmd_te
);
829 g_object_set_data(G_OBJECT(ok_bt
), PRINT_ARGS_KEY
, args
);
830 g_object_set_data(G_OBJECT(ok_bt
), PRINT_FILE_TE_KEY
, file_te
);
831 g_object_set_data(G_OBJECT(ok_bt
), PRINT_SUMMARY_CB_KEY
, summary_cb
);
832 g_object_set_data(G_OBJECT(ok_bt
), PRINT_COL_HEADINGS_CB_KEY
, col_headings_cb
);
833 g_object_set_data(G_OBJECT(ok_bt
), PRINT_DETAILS_CB_KEY
, details_cb
);
834 g_object_set_data(G_OBJECT(ok_bt
), PRINT_COLLAPSE_ALL_RB_KEY
, collapse_all_rb
);
835 g_object_set_data(G_OBJECT(ok_bt
), PRINT_AS_DISPLAYED_RB_KEY
, as_displayed_rb
);
836 g_object_set_data(G_OBJECT(ok_bt
), PRINT_EXPAND_ALL_RB_KEY
, expand_all_rb
);
837 g_object_set_data(G_OBJECT(ok_bt
), PRINT_HEX_CB_KEY
, hex_cb
);
838 g_object_set_data(G_OBJECT(ok_bt
), PRINT_FORMFEED_CB_KEY
, formfeed_cb
);
839 g_signal_connect(ok_bt
, "clicked", G_CALLBACK(print_ok_cb
), main_win
);
840 gtk_widget_set_tooltip_text (ok_bt
, "Start output");
842 cancel_bt
= (GtkWidget
*)g_object_get_data(G_OBJECT(bbox
), GTK_STOCK_CANCEL
);
843 window_set_cancel_button(main_win
, cancel_bt
, window_cancel_button_cb
);
844 gtk_widget_set_tooltip_text (cancel_bt
, "Cancel and exit dialog");
846 if(action
== output_action_print
) {
847 help_bt
= (GtkWidget
*)g_object_get_data(G_OBJECT(bbox
), GTK_STOCK_HELP
);
848 g_signal_connect(help_bt
, "clicked", G_CALLBACK(topic_cb
), (gpointer
)HELP_PRINT_DIALOG
);
851 help_bt
= (GtkWidget
*)g_object_get_data(G_OBJECT(bbox
), GTK_STOCK_HELP
);
852 g_signal_connect(help_bt
, "clicked", G_CALLBACK(topic_cb
), (gpointer
)HELP_EXPORT_FILE_WIN32_DIALOG
);
854 help_bt
= (GtkWidget
*)g_object_get_data(G_OBJECT(bbox
), GTK_STOCK_HELP
);
855 g_signal_connect(help_bt
, "clicked", G_CALLBACK(topic_cb
), (gpointer
)HELP_EXPORT_FILE_DIALOG
);
859 gtk_widget_grab_default(ok_bt
);
861 /* Catch the "activate" signal on the "Command" and "File" text entries,
862 so that if the user types Return there, we act as if the "OK" button
863 had been selected, as happens if Return is typed if some widget
864 that *doesn't* handle the Return key has the input focus. */
866 dlg_set_activate(cmd_te
, ok_bt
);
868 if(action
!= output_action_print
)
869 dlg_set_activate(file_te
, ok_bt
);
871 g_signal_connect(main_win
, "delete_event", G_CALLBACK(window_delete_event_cb
), NULL
);
873 gtk_widget_show(main_win
);
874 window_present(main_win
);
880 /* user changed "print to" destination */
882 print_cmd_toggle_dest(GtkWidget
*widget
, gpointer data _U_
)
885 GtkWidget
*cmd_lb
, *cmd_te
;
887 GtkWidget
*file_bt
, *file_te
;
891 cmd_lb
= GTK_WIDGET(g_object_get_data(G_OBJECT(widget
), PRINT_CMD_LB_KEY
));
892 cmd_te
= GTK_WIDGET(g_object_get_data(G_OBJECT(widget
), PRINT_CMD_TE_KEY
));
894 file_bt
= GTK_WIDGET(g_object_get_data(G_OBJECT(widget
), PRINT_FILE_BT_KEY
));
895 file_te
= GTK_WIDGET(g_object_get_data(G_OBJECT(widget
), PRINT_FILE_TE_KEY
));
897 to_file
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (widget
));
899 gtk_widget_set_sensitive(cmd_lb
, !to_file
);
900 gtk_widget_set_sensitive(cmd_te
, !to_file
);
902 gtk_widget_set_sensitive(file_bt
, to_file
);
903 gtk_widget_set_sensitive(file_te
, to_file
);
907 /* user changed "packet details" */
909 print_cmd_toggle_detail(GtkWidget
*widget _U_
, gpointer data
)
911 GtkWidget
*print_bt
, *summary_cb
, *col_headings_cb
, *details_cb
;
912 GtkWidget
*collapse_all_rb
, *expand_all_rb
, *as_displayed_rb
, *hex_cb
;
913 gboolean print_detail
, print_summary
;
915 print_bt
= GTK_WIDGET(g_object_get_data(G_OBJECT(data
), PRINT_BT_KEY
));
916 summary_cb
= GTK_WIDGET(g_object_get_data(G_OBJECT(data
), PRINT_SUMMARY_CB_KEY
));
917 col_headings_cb
= GTK_WIDGET(g_object_get_data(G_OBJECT(data
), PRINT_COL_HEADINGS_CB_KEY
));
918 details_cb
= GTK_WIDGET(g_object_get_data(G_OBJECT(data
), PRINT_DETAILS_CB_KEY
));
919 collapse_all_rb
= GTK_WIDGET(g_object_get_data(G_OBJECT(data
), PRINT_COLLAPSE_ALL_RB_KEY
));
920 as_displayed_rb
= GTK_WIDGET(g_object_get_data(G_OBJECT(data
), PRINT_AS_DISPLAYED_RB_KEY
));
921 expand_all_rb
= GTK_WIDGET(g_object_get_data(G_OBJECT(data
), PRINT_EXPAND_ALL_RB_KEY
));
922 hex_cb
= GTK_WIDGET(g_object_get_data(G_OBJECT(data
), PRINT_HEX_CB_KEY
));
924 /* If user disabled summary, disable the column headings checkbox too. */
925 print_summary
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (summary_cb
));
926 gtk_widget_set_sensitive(col_headings_cb
, print_summary
);
928 /* If user disabled details, disable the corresponding buttons */
929 print_detail
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (details_cb
));
930 gtk_widget_set_sensitive(collapse_all_rb
, print_detail
);
931 gtk_widget_set_sensitive(as_displayed_rb
, print_detail
);
932 gtk_widget_set_sensitive(expand_all_rb
, print_detail
);
934 /* if user selected nothing to print at all, disable the "ok" button */
935 gtk_widget_set_sensitive(print_bt
,
936 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (summary_cb
)) ||
937 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (details_cb
)) ||
938 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (hex_cb
)));
943 print_ok_cb(GtkWidget
*ok_bt
, gpointer parent_w
)
950 gboolean export_as_pdml
= FALSE
, export_as_psml
= FALSE
;
951 gboolean export_as_csv
= FALSE
;
952 gboolean export_as_carrays
= FALSE
;
954 gboolean win_printer
= FALSE
;
957 char *tmp_oldfile
= NULL
;
959 cf_print_status_t status
;
961 args
= (print_args_t
*)g_object_get_data(G_OBJECT(ok_bt
), PRINT_ARGS_KEY
);
963 /* Check whether the range is valid. */
964 if (!range_check_validity(&args
->range
)) {
965 /* The range isn't valid; don't dismiss the print/export dialog box,
966 just leave it around so that the user can, after they
967 dismiss the alert box popped up for the error, try again. */
971 button
= (GtkWidget
*)g_object_get_data(G_OBJECT(ok_bt
), PRINT_DEST_CB_KEY
);
972 args
->to_file
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button
));
975 g_dest
= gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(ok_bt
),
976 PRINT_FILE_TE_KEY
)));
978 simple_dialog(ESD_TYPE_ERROR
, ESD_BTN_OK
,
979 "Output to file, but no file specified.");
983 args
->file
= g_strdup(g_dest
);
984 /* Save the directory name for future file dialogs. */
985 f_name
= g_strdup(g_dest
);
986 dirname
= get_dirname(f_name
); /* Overwrites f_name */
987 set_last_open_dir(dirname
);
992 /* We currently don't have a function in util.h to create just a tempfile */
993 /* name, so simply create a tempfile using the "official" function, */
994 /* then delete this file again. After this, the name MUST be available. */
996 /* Don't use tmpnam() or such, as this will fail under some ACL */
997 /* circumstances: http://bugs.wireshark.org/bugzilla/show_bug.cgi?id=358 */
998 /* Also: tmpnam is "insecure" and should not be used. */
999 tmp_fd
= create_tempfile(&tmp_namebuf
, "wshprint");
1001 simple_dialog(ESD_TYPE_ERROR
, ESD_BTN_OK
,
1002 "Couldn't create a temporary file for printing:\n%s", tmp_namebuf
);
1005 /* remember to restore these values later! */
1006 tmp_oldfile
= args
->file
;
1007 args
->file
= g_strdup(tmp_namebuf
);
1008 ws_unlink(args
->file
);
1009 args
->to_file
= TRUE
;
1012 args
->cmd
= g_strdup(gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(ok_bt
),
1013 PRINT_CMD_TE_KEY
))));
1017 args
->format
= PR_FMT_TEXT
;
1018 button
= (GtkWidget
*)g_object_get_data(G_OBJECT(ok_bt
), PRINT_PS_RB_KEY
);
1019 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button
)))
1020 args
->format
= PR_FMT_PS
;
1021 button
= (GtkWidget
*)g_object_get_data(G_OBJECT(ok_bt
), PRINT_PDML_RB_KEY
);
1022 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button
)))
1023 export_as_pdml
= TRUE
;
1024 button
= (GtkWidget
*)g_object_get_data(G_OBJECT(ok_bt
), PRINT_PSML_RB_KEY
);
1025 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button
)))
1026 export_as_psml
= TRUE
;
1027 button
= (GtkWidget
*)g_object_get_data(G_OBJECT(ok_bt
), PRINT_CSV_RB_KEY
);
1028 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button
)))
1029 export_as_csv
= TRUE
;
1030 button
= (GtkWidget
*)g_object_get_data(G_OBJECT(ok_bt
), PRINT_CARRAYS_RB_KEY
);
1031 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button
)))
1032 export_as_carrays
= TRUE
;
1034 button
= (GtkWidget
*)g_object_get_data(G_OBJECT(ok_bt
), PRINT_SUMMARY_CB_KEY
);
1035 args
->print_summary
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button
));
1037 button
= (GtkWidget
*)g_object_get_data(G_OBJECT(ok_bt
), PRINT_COL_HEADINGS_CB_KEY
);
1038 args
->print_col_headings
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button
));
1040 button
= (GtkWidget
*)g_object_get_data(G_OBJECT(ok_bt
), PRINT_COLLAPSE_ALL_RB_KEY
);
1041 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button
))) {
1042 args
->print_dissections
= print_dissections_collapsed
;
1044 button
= (GtkWidget
*)g_object_get_data(G_OBJECT(ok_bt
), PRINT_AS_DISPLAYED_RB_KEY
);
1045 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button
))) {
1046 args
->print_dissections
= print_dissections_as_displayed
;
1048 button
= (GtkWidget
*)g_object_get_data(G_OBJECT(ok_bt
), PRINT_EXPAND_ALL_RB_KEY
);
1049 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button
))) {
1050 args
->print_dissections
= print_dissections_expanded
;
1053 /* the details setting has priority over the radio buttons */
1054 button
= (GtkWidget
*)g_object_get_data(G_OBJECT(ok_bt
), PRINT_DETAILS_CB_KEY
);
1055 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button
))) {
1056 args
->print_dissections
= print_dissections_none
;
1059 button
= (GtkWidget
*)g_object_get_data(G_OBJECT(ok_bt
), PRINT_HEX_CB_KEY
);
1060 args
->print_hex
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button
));
1062 button
= (GtkWidget
*)g_object_get_data(G_OBJECT(ok_bt
), PRINT_FORMFEED_CB_KEY
);
1063 args
->print_formfeed
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button
));
1066 window_destroy(GTK_WIDGET(parent_w
));
1068 /* Now print/export the packets */
1070 status
= cf_write_pdml_packets(&cfile
, args
);
1071 else if (export_as_psml
)
1072 status
= cf_write_psml_packets(&cfile
, args
);
1073 else if (export_as_csv
)
1074 status
= cf_write_csv_packets(&cfile
, args
);
1075 else if (export_as_carrays
)
1076 status
= cf_write_carrays_packets(&cfile
, args
);
1078 switch (args
->format
) {
1081 if (args
->to_file
) {
1082 args
->stream
= print_stream_text_new(TRUE
, args
->file
);
1083 if (args
->stream
== NULL
) {
1084 open_failure_alert_box(args
->file
, errno
, TRUE
);
1088 args
->stream
= print_stream_text_new(FALSE
, args
->cmd
);
1089 if (args
->stream
== NULL
) {
1090 simple_dialog(ESD_TYPE_ERROR
, ESD_BTN_OK
,
1091 "Couldn't run print command %s.", args
->cmd
);
1097 if (args
->to_file
) {
1098 args
->stream
= print_stream_ps_new(TRUE
, args
->file
);
1099 if (args
->stream
== NULL
) {
1100 open_failure_alert_box(args
->file
, errno
, TRUE
);
1104 args
->stream
= print_stream_ps_new(FALSE
, args
->cmd
);
1105 if (args
->stream
== NULL
) {
1106 simple_dialog(ESD_TYPE_ERROR
, ESD_BTN_OK
,
1107 "Couldn't run print command %s.", args
->cmd
);
1113 g_assert_not_reached();
1116 status
= cf_print_packets(&cfile
, args
);
1123 case CF_PRINT_OPEN_ERROR
:
1125 open_failure_alert_box(args
->file
, errno
, TRUE
);
1127 simple_dialog(ESD_TYPE_ERROR
, ESD_BTN_OK
, "Couldn't run print command %s.",
1131 case CF_PRINT_WRITE_ERROR
:
1133 write_failure_alert_box(args
->file
, errno
);
1135 simple_dialog(ESD_TYPE_ERROR
, ESD_BTN_OK
,
1136 "Error writing to print command: %s", g_strerror(errno
));
1142 print_mswin(args
->file
);
1144 /* trash temp file */
1145 ws_remove(args
->file
);
1148 /* restore old settings */
1149 args
->to_file
= FALSE
;
1150 args
->file
= tmp_oldfile
;
1156 print_destroy_cb(GtkWidget
*win
, gpointer user_data
)
1160 /* Is there a file selection dialog associated with this
1161 Print File dialog? */
1162 fs
= (GtkWidget
*)g_object_get_data(G_OBJECT(win
), E_FILE_SEL_DIALOG_PTR_KEY
);
1165 /* Yes. Destroy it. */
1169 /* Note that we no longer have a "Print" dialog box. */
1170 *((gpointer
*) user_data
) = NULL
;