From 84aef00badab1fbcc1429b138e583b2245673e17 Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Sun, 30 Apr 2006 01:47:58 +0000 Subject: Move the file selection dialog routines to file_dlg.c, and give it a header file. #if 0 out some includes; if none of the builds have a problem with that, I'll remove them. svn path=/trunk/; revision=18036 --- gtk/Makefile.am | 1 + gtk/Makefile.common | 1 + gtk/about_dlg.c | 1 + gtk/capture_dlg.c | 1 + gtk/capture_file_dlg.c | 3 + gtk/dlg_utils.c | 302 ++----------------------------------------- gtk/dlg_utils.h | 79 ------------ gtk/file_dlg.c | 342 +++++++++++++++++++++++++++++++++++++++++++++++++ gtk/file_dlg.h | 114 +++++++++++++++++ gtk/follow_dlg.c | 1 + gtk/graph_analysis.c | 3 + gtk/main.c | 3 + gtk/print_dlg.c | 1 + gtk/print_prefs.c | 3 + gtk/proto_draw.c | 3 + gtk/recent.c | 3 + gtk/rtp_analysis.c | 1 + gtk/rtp_stream_dlg.c | 1 + gtk/ssl-dlg.c | 1 + 19 files changed, 493 insertions(+), 371 deletions(-) create mode 100644 gtk/file_dlg.c create mode 100644 gtk/file_dlg.h (limited to 'gtk') diff --git a/gtk/Makefile.am b/gtk/Makefile.am index 063c31ede7..7bae6f4212 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -54,6 +54,7 @@ noinst_HEADERS = \ dfilter_expr_dlg.h \ dlg_utils.h \ expert_comp_table.h \ + file_dlg.h \ fileset_dlg.h \ filter_dlg.h \ find_dlg.h \ diff --git a/gtk/Makefile.common b/gtk/Makefile.common index 66dc577575..74ea6c9dc8 100644 --- a/gtk/Makefile.common +++ b/gtk/Makefile.common @@ -59,6 +59,7 @@ ETHEREAL_GTK_SRC = \ drag_and_drop.c \ ethereal-tap-register.c \ expert_comp_table.c \ + file_dlg.c \ fileset_dlg.c \ filter_dlg.c \ find_dlg.c \ diff --git a/gtk/about_dlg.c b/gtk/about_dlg.c index da0476c744..7d0401d0c0 100644 --- a/gtk/about_dlg.c +++ b/gtk/about_dlg.c @@ -34,6 +34,7 @@ #include "about_dlg.h" #include "gui_utils.h" #include "dlg_utils.h" +#include "file_dlg.h" #include "compat_macros.h" #include "globals.h" #if GTK_MAJOR_VERSION >= 2 || GTK_MINOR_VERSION >= 3 diff --git a/gtk/capture_dlg.c b/gtk/capture_dlg.c index 33e1e0ec6d..55e6703108 100644 --- a/gtk/capture_dlg.c +++ b/gtk/capture_dlg.c @@ -45,6 +45,7 @@ #include "filter_dlg.h" #include "simple_dialog.h" #include "dlg_utils.h" +#include "file_dlg.h" #include "capture-pcap-util.h" #include "capture_ui_utils.h" #include diff --git a/gtk/capture_file_dlg.c b/gtk/capture_file_dlg.c index 6c9232e20a..57632e90ab 100644 --- a/gtk/capture_file_dlg.c +++ b/gtk/capture_file_dlg.c @@ -42,7 +42,10 @@ #include "alert_box.h" #include "simple_dialog.h" #include "menu.h" +#if 0 #include "dlg_utils.h" +#endif +#include "file_dlg.h" #include "capture_file_dlg.h" #include "main.h" #include "compat_macros.h" diff --git a/gtk/dlg_utils.c b/gtk/dlg_utils.c index 6af8bd0fbb..5c81c3900c 100644 --- a/gtk/dlg_utils.c +++ b/gtk/dlg_utils.c @@ -27,40 +27,35 @@ #endif #include +#if 0 #include +#endif +#if 0 #include +#endif +#if 0 #include "globals.h" +#endif #include "gtkglobals.h" #include "gui_utils.h" #include "dlg_utils.h" -#include "keys.h" #include "compat_macros.h" +#if 0 #include "main.h" +#endif #include +#if 0 #include +#endif #include - -/* Keys ... */ -#define E_FS_CALLER_PTR_KEY "fs_caller_ptr" - -static gchar *last_open_dir = NULL; -static gboolean updated_last_open_dir = FALSE; - - static void dlg_activate (GtkWidget *widget, gpointer ok_button); -#if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION < 4) || GTK_MAJOR_VERSION < 2 -static void file_selection_browse_ok_cb(GtkWidget *w, gpointer data); -#endif -static void file_selection_browse_destroy_cb(GtkWidget *win, GtkWidget* file_te); - - /* create a button for the button row (helper for dlg_button_row_new) */ static GtkWidget * dlg_button_new(GtkWidget *hbox, GtkWidget *button_hbox, const gchar *stock_id) @@ -374,283 +369,6 @@ dlg_window_new(const gchar *title) return win; } - -/* Create a file selection dialog box window that belongs to Ethereal's - main window. */ -#if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2 -GtkWidget * -file_selection_new(const gchar *title, file_selection_action_t action) -{ - GtkWidget *win; - GtkFileChooserAction gtk_action; - const gchar *ok_button_text; - - switch (action) { - - case FILE_SELECTION_OPEN: - gtk_action = GTK_FILE_CHOOSER_ACTION_OPEN; - ok_button_text = GTK_STOCK_OPEN; - break; - - case FILE_SELECTION_READ_BROWSE: - gtk_action = GTK_FILE_CHOOSER_ACTION_OPEN; - ok_button_text = GTK_STOCK_OK; - break; - - case FILE_SELECTION_SAVE: - gtk_action = GTK_FILE_CHOOSER_ACTION_SAVE; - ok_button_text = GTK_STOCK_SAVE; - break; - - case FILE_SELECTION_WRITE_BROWSE: - gtk_action = GTK_FILE_CHOOSER_ACTION_SAVE; - ok_button_text = GTK_STOCK_OK; - break; - - default: - g_assert_not_reached(); - gtk_action = -1; - ok_button_text = NULL; - break; - } - win = gtk_file_chooser_dialog_new(title, GTK_WINDOW(top_level), gtk_action, -#ifndef _WIN32 - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - ok_button_text, GTK_RESPONSE_ACCEPT, -#else - ok_button_text, GTK_RESPONSE_ACCEPT, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, -#endif - NULL); - - /* If we've opened a file before, start out by showing the files in the directory - in which that file resided. */ - if (last_open_dir) - file_selection_set_current_folder(win, last_open_dir); - - return win; -} -#else -GtkWidget * -file_selection_new(const gchar *title, file_selection_action_t action _U_) -{ - GtkWidget *win; - - win = gtk_file_selection_new(title); -#if GTK_MAJOR_VERSION >= 2 - gtk_window_set_position(GTK_WINDOW(win), GTK_WIN_POS_CENTER_ON_PARENT); -#endif - gtk_window_set_transient_for(GTK_WINDOW(win), GTK_WINDOW(top_level)); - - /* XXX - why are we doing this? We don't do it with the GtkFileChooser, - as it complains that the file name isn't being set to an absolute - path; does this provoke a similar complaint? */ - gtk_file_selection_set_filename(GTK_FILE_SELECTION(win), ""); - - /* If we've opened a file before, start out by showing the files in the directory - in which that file resided. */ - if (last_open_dir) - file_selection_set_current_folder(win, last_open_dir); - - return win; -} -#endif - -/* Set the current folder for a file selection dialog. */ -gboolean -file_selection_set_current_folder(GtkWidget *fs, const gchar *filename) -{ -#if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2 - gboolean ret; - int filename_len = strlen(filename); - gchar *new_filename; - - /* trim filename, so gtk_file_chooser_set_current_folder() likes it, see below */ - if (filename[filename_len -1] == G_DIR_SEPARATOR -#ifdef _WIN32 - && filename_len > 3) /* e.g. "D:\" */ -#else - && filename_len > 1) /* e.g. "/" */ -#endif - { - new_filename = g_strdup(filename); - new_filename[filename_len-1] = '\0'; - } else { - new_filename = g_strdup(filename); - } - - /* this function is very pedantic about it's filename parameter */ - /* no trailing '\' allowed, unless a win32 root dir "D:\" */ - ret = gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(fs), new_filename); - g_free(new_filename); - return ret; -#else - gtk_file_selection_set_filename(GTK_FILE_SELECTION(fs), filename); - return TRUE; -#endif -} - -/* Set the "extra" widget for a file selection dialog, with user-supplied - options. */ -void -file_selection_set_extra_widget(GtkWidget *fs, GtkWidget *extra) -{ -#if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2 - gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(fs), extra); -#else - gtk_box_pack_start(GTK_BOX(GTK_FILE_SELECTION(fs)->action_area), extra, - FALSE, FALSE, 0); -#endif -} - - -/* - * A generic select_file routine that is intended to be connected to - * a Browse button on other dialog boxes. This allows the user to browse - * for a file and select it. We fill in the text_entry that is given to us. - * - * We display the window label specified in our args. - */ -void -file_selection_browse(GtkWidget *file_bt, GtkWidget *file_te, const char *label, file_selection_action_t action) -{ - GtkWidget *caller = gtk_widget_get_toplevel(file_bt); - GtkWidget *fs; -#if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2 - gchar *f_name; -#endif - - /* Has a file selection dialog box already been opened for that top-level - widget? */ - fs = OBJECT_GET_DATA(caller, E_FILE_SEL_DIALOG_PTR_KEY); - if (fs != NULL) { - /* Yes. Just re-activate that dialog box. */ - reactivate_window(fs); - return; - } - - fs = file_selection_new(label, action); - - OBJECT_SET_DATA(fs, PRINT_FILE_TE_KEY, file_te); - - /* Set the E_FS_CALLER_PTR_KEY for the new dialog to point to our caller. */ - OBJECT_SET_DATA(fs, E_FS_CALLER_PTR_KEY, caller); - - /* Set the E_FILE_SEL_DIALOG_PTR_KEY for the caller to point to us */ - OBJECT_SET_DATA(caller, E_FILE_SEL_DIALOG_PTR_KEY, fs); - - /* Call a handler when the file selection box is destroyed, so we can inform - our caller, if any, that it's been destroyed. */ - SIGNAL_CONNECT(fs, "destroy", GTK_SIGNAL_FUNC(file_selection_browse_destroy_cb), - file_te); - -#if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2 - if (gtk_dialog_run(GTK_DIALOG(fs)) == GTK_RESPONSE_ACCEPT) - { - f_name = g_strdup(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fs))); - gtk_entry_set_text(GTK_ENTRY(file_te), f_name); - g_free(f_name); - } - window_destroy(fs); -#else - SIGNAL_CONNECT(GTK_FILE_SELECTION(fs)->ok_button, "clicked", - file_selection_browse_ok_cb, fs); - - window_set_cancel_button(fs, GTK_FILE_SELECTION(fs)->cancel_button, - window_cancel_button_cb); - - SIGNAL_CONNECT(fs, "delete_event", window_delete_event_cb, fs); - - gtk_widget_show(fs); - window_present(fs); -#endif -} - - -#if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION < 4) || GTK_MAJOR_VERSION < 2 -static void -file_selection_browse_ok_cb(GtkWidget *w _U_, gpointer data) -{ - gchar *f_name; - GtkWidget *win = data; - - f_name = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION (data))); - - /* Perhaps the user specified a directory instead of a file. - Check whether they did. */ - if (test_for_directory(f_name) == EISDIR) { - /* It's a directory - set the file selection box to display it. */ - set_last_open_dir(f_name); - g_free(f_name); - file_selection_set_current_folder(data, last_open_dir); - return; - } - - gtk_entry_set_text(GTK_ENTRY(OBJECT_GET_DATA(win, PRINT_FILE_TE_KEY)), - f_name); - window_destroy(GTK_WIDGET(win)); - - g_free(f_name); -} -#endif - -static void -file_selection_browse_destroy_cb(GtkWidget *win, GtkWidget* parent_te) -{ - GtkWidget *caller; - - /* Get the widget that requested that we be popped up. - (It should arrange to destroy us if it's destroyed, so - that we don't get a pointer to a non-existent window here.) */ - caller = OBJECT_GET_DATA(win, E_FS_CALLER_PTR_KEY); - - /* Tell it we no longer exist. */ - OBJECT_SET_DATA(caller, E_FILE_SEL_DIALOG_PTR_KEY, NULL); - - /* Give the focus to the file text entry widget so the user can just press - Return to print to the file. */ - gtk_widget_grab_focus(parent_te); -} - - -void -set_last_open_dir(char *dirname) -{ - int len; - gchar *new_last_open_dir; - - if (dirname) { - len = strlen(dirname); - if (dirname[len-1] == G_DIR_SEPARATOR) { - new_last_open_dir = g_strconcat(dirname, NULL); - } - else { - new_last_open_dir = g_strconcat(dirname, - G_DIR_SEPARATOR_S, NULL); - } - - if (last_open_dir == NULL || - strcmp(last_open_dir, new_last_open_dir) != 0) - updated_last_open_dir = TRUE; - } - else { - new_last_open_dir = NULL; - if (last_open_dir != NULL) - updated_last_open_dir = TRUE; - } - - if (last_open_dir) { - g_free(last_open_dir); - } - last_open_dir = new_last_open_dir; -} - -char * -get_last_open_dir(void) -{ - return last_open_dir; -} - /* Set the "activate" signal for a widget to call a routine to activate the "OK" button for a dialog box. diff --git a/gtk/dlg_utils.h b/gtk/dlg_utils.h index 4317eb92a8..03135d7399 100644 --- a/gtk/dlg_utils.h +++ b/gtk/dlg_utils.h @@ -27,8 +27,6 @@ * Dialogs are specially created windows and are related to their parent windows (usually the main window). * See: @ref howto_window_page for details. * - * @section normal_dialogs Normal dialogs - * * Normal dialogs are created using dlg_window_new(). * * - "About" about_ethereal_cb() @@ -60,22 +58,6 @@ * - "Tcp Graph Control" control_panel_create() * - "Help for TCP graphing" callback_create_help() * - "Tcp Graph Magnify" magnify_create() - * - * @section file_sel_dialogs File selection dialogs - * - * File selection dialogs are created using file_selection_new(). - * - * - "Browse" file_selection_browse() - * - "Open Capture File" file_open_cmd() - * - "Save Capture File As" file_save_as_cmd() - * - "Import Color Filters" file_color_import_cmd_cb() - * - "Export Color Filters" file_color_export_cmd_cb() - * - "Save TCP Follow Stream As" follow_save_as_cmd_cb() - * - "Export Selected Packet Bytes" savehex_cb() - * - "Save Data As CSV" save_csv_as_cb() - * - "Save Payload As ..." on_save_bt_clicked() - * - "Save selected stream in rtpdump" rtpstream_on_save() - * */ /** @file @@ -97,67 +79,6 @@ */ extern GtkWidget *dlg_window_new(const gchar *title); -/** the action a file selection is designed for */ -typedef enum { - FILE_SELECTION_OPEN, /**< open a file */ - FILE_SELECTION_READ_BROWSE, /**< browse for a file to read */ - FILE_SELECTION_SAVE, /**< save/export a file */ - FILE_SELECTION_WRITE_BROWSE /**< browse for a file to write to */ -} file_selection_action_t; - -/** Create a file selection dialog box window that belongs to Ethereal's - * main window. See window_new() for usage. - * - * @param title the title for the new file selection dialog - * @param action the desired action - * @return the newly created file selection dialog - */ -extern GtkWidget *file_selection_new(const gchar *title, file_selection_action_t action); - -/** Set the current folder for a file selection dialog. - * - * @param fs the file selection dialog from file_selection_new() - * @param filename the folder to set - * @return TRUE if the folder could be changed successfully - */ -extern gboolean file_selection_set_current_folder(GtkWidget *fs, const gchar *filename); - -/** Set the "extra" widget for a file selection dialog. This is needed to support - * user-supplied options. - * - * @param fs the file selection dialog from file_selection_new() - * @param extra the widget to set - */ -extern void file_selection_set_extra_widget(GtkWidget *fs, GtkWidget *extra); - -/** The function file_selection_browse() will OBJECT_SET_DATA() itself on it's parent window. - * When destroying the parent window, it can close the corresponding file selection. */ -#define E_FILE_SEL_DIALOG_PTR_KEY "file_sel_dialog_ptr" - -/** Browse the files and fill in the associated text entry. - * - * @param file_bt the button that called us (to get the toplevel widget) - * @param file_te the GtkEntry the dialog will have to fill in the filename - * @param title the title for the file selection dialog - * @param action the desired action - */ -extern void -file_selection_browse(GtkWidget *file_bt, GtkWidget *file_te, const char *title, file_selection_action_t action); - -/** Get the latest opened directory. - * - * @return the dirname - */ -extern char *get_last_open_dir(void); - -/** Set the latest opened directory. - * Will already be done when using file_selection_new(). - * - * @param dirname the dirname - */ -extern void set_last_open_dir(char *dirname); - - /** Create a button row (with variable number of buttons) for a dialog. * The button widgets will be available by OBJECT_GET_DATA(dlg, stock_id) later. * diff --git a/gtk/file_dlg.c b/gtk/file_dlg.c new file mode 100644 index 0000000000..71eafd5b3b --- /dev/null +++ b/gtk/file_dlg.c @@ -0,0 +1,342 @@ +/* file_dlg.c + * Utilities to use when constructing file selection dialogs + * + * $Id$ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 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 +#if 0 +#include +#endif + +#include + +#if 0 +#include "globals.h" +#endif + +#include "gtkglobals.h" +#include "gui_utils.h" +#if 0 +#include "dlg_utils.h" +#endif +#include "file_dlg.h" +#include "keys.h" +#include "compat_macros.h" +#if 0 +#include "main.h" +#endif + +#include +#if 0 +#include +#endif + +static gchar *last_open_dir = NULL; +static gboolean updated_last_open_dir = FALSE; + +#if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION < 4) || GTK_MAJOR_VERSION < 2 +static void file_selection_browse_ok_cb(GtkWidget *w, gpointer data); +#endif +static void file_selection_browse_destroy_cb(GtkWidget *win, GtkWidget* file_te); + +/* Keys ... */ +#define E_FS_CALLER_PTR_KEY "fs_caller_ptr" + +/* Create a file selection dialog box window that belongs to Ethereal's + main window. */ +#if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2 +GtkWidget * +file_selection_new(const gchar *title, file_selection_action_t action) +{ + GtkWidget *win; + GtkFileChooserAction gtk_action; + const gchar *ok_button_text; + + switch (action) { + + case FILE_SELECTION_OPEN: + gtk_action = GTK_FILE_CHOOSER_ACTION_OPEN; + ok_button_text = GTK_STOCK_OPEN; + break; + + case FILE_SELECTION_READ_BROWSE: + gtk_action = GTK_FILE_CHOOSER_ACTION_OPEN; + ok_button_text = GTK_STOCK_OK; + break; + + case FILE_SELECTION_SAVE: + gtk_action = GTK_FILE_CHOOSER_ACTION_SAVE; + ok_button_text = GTK_STOCK_SAVE; + break; + + case FILE_SELECTION_WRITE_BROWSE: + gtk_action = GTK_FILE_CHOOSER_ACTION_SAVE; + ok_button_text = GTK_STOCK_OK; + break; + + default: + g_assert_not_reached(); + gtk_action = -1; + ok_button_text = NULL; + break; + } + win = gtk_file_chooser_dialog_new(title, GTK_WINDOW(top_level), gtk_action, +#ifndef _WIN32 + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + ok_button_text, GTK_RESPONSE_ACCEPT, +#else + ok_button_text, GTK_RESPONSE_ACCEPT, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, +#endif + NULL); + + /* If we've opened a file before, start out by showing the files in the directory + in which that file resided. */ + if (last_open_dir) + file_selection_set_current_folder(win, last_open_dir); + + return win; +} +#else +GtkWidget * +file_selection_new(const gchar *title, file_selection_action_t action _U_) +{ + GtkWidget *win; + + win = gtk_file_selection_new(title); +#if GTK_MAJOR_VERSION >= 2 + gtk_window_set_position(GTK_WINDOW(win), GTK_WIN_POS_CENTER_ON_PARENT); +#endif + gtk_window_set_transient_for(GTK_WINDOW(win), GTK_WINDOW(top_level)); + + /* XXX - why are we doing this? We don't do it with the GtkFileChooser, + as it complains that the file name isn't being set to an absolute + path; does this provoke a similar complaint? */ + gtk_file_selection_set_filename(GTK_FILE_SELECTION(win), ""); + + /* If we've opened a file before, start out by showing the files in the directory + in which that file resided. */ + if (last_open_dir) + file_selection_set_current_folder(win, last_open_dir); + + return win; +} +#endif + +/* Set the current folder for a file selection dialog. */ +gboolean +file_selection_set_current_folder(GtkWidget *fs, const gchar *filename) +{ +#if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2 + gboolean ret; + int filename_len = strlen(filename); + gchar *new_filename; + + /* trim filename, so gtk_file_chooser_set_current_folder() likes it, see below */ + if (filename[filename_len -1] == G_DIR_SEPARATOR +#ifdef _WIN32 + && filename_len > 3) /* e.g. "D:\" */ +#else + && filename_len > 1) /* e.g. "/" */ +#endif + { + new_filename = g_strdup(filename); + new_filename[filename_len-1] = '\0'; + } else { + new_filename = g_strdup(filename); + } + + /* this function is very pedantic about it's filename parameter */ + /* no trailing '\' allowed, unless a win32 root dir "D:\" */ + ret = gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(fs), new_filename); + g_free(new_filename); + return ret; +#else + gtk_file_selection_set_filename(GTK_FILE_SELECTION(fs), filename); + return TRUE; +#endif +} + +/* Set the "extra" widget for a file selection dialog, with user-supplied + options. */ +void +file_selection_set_extra_widget(GtkWidget *fs, GtkWidget *extra) +{ +#if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2 + gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(fs), extra); +#else + gtk_box_pack_start(GTK_BOX(GTK_FILE_SELECTION(fs)->action_area), extra, + FALSE, FALSE, 0); +#endif +} + + +/* + * A generic select_file routine that is intended to be connected to + * a Browse button on other dialog boxes. This allows the user to browse + * for a file and select it. We fill in the text_entry that is given to us. + * + * We display the window label specified in our args. + */ +void +file_selection_browse(GtkWidget *file_bt, GtkWidget *file_te, const char *label, file_selection_action_t action) +{ + GtkWidget *caller = gtk_widget_get_toplevel(file_bt); + GtkWidget *fs; +#if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2 + gchar *f_name; +#endif + + /* Has a file selection dialog box already been opened for that top-level + widget? */ + fs = OBJECT_GET_DATA(caller, E_FILE_SEL_DIALOG_PTR_KEY); + if (fs != NULL) { + /* Yes. Just re-activate that dialog box. */ + reactivate_window(fs); + return; + } + + fs = file_selection_new(label, action); + + OBJECT_SET_DATA(fs, PRINT_FILE_TE_KEY, file_te); + + /* Set the E_FS_CALLER_PTR_KEY for the new dialog to point to our caller. */ + OBJECT_SET_DATA(fs, E_FS_CALLER_PTR_KEY, caller); + + /* Set the E_FILE_SEL_DIALOG_PTR_KEY for the caller to point to us */ + OBJECT_SET_DATA(caller, E_FILE_SEL_DIALOG_PTR_KEY, fs); + + /* Call a handler when the file selection box is destroyed, so we can inform + our caller, if any, that it's been destroyed. */ + SIGNAL_CONNECT(fs, "destroy", GTK_SIGNAL_FUNC(file_selection_browse_destroy_cb), + file_te); + +#if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2 + if (gtk_dialog_run(GTK_DIALOG(fs)) == GTK_RESPONSE_ACCEPT) + { + f_name = g_strdup(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fs))); + gtk_entry_set_text(GTK_ENTRY(file_te), f_name); + g_free(f_name); + } + window_destroy(fs); +#else + SIGNAL_CONNECT(GTK_FILE_SELECTION(fs)->ok_button, "clicked", + file_selection_browse_ok_cb, fs); + + window_set_cancel_button(fs, GTK_FILE_SELECTION(fs)->cancel_button, + window_cancel_button_cb); + + SIGNAL_CONNECT(fs, "delete_event", window_delete_event_cb, fs); + + gtk_widget_show(fs); + window_present(fs); +#endif +} + + +#if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION < 4) || GTK_MAJOR_VERSION < 2 +static void +file_selection_browse_ok_cb(GtkWidget *w _U_, gpointer data) +{ + gchar *f_name; + GtkWidget *win = data; + + f_name = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION (data))); + + /* Perhaps the user specified a directory instead of a file. + Check whether they did. */ + if (test_for_directory(f_name) == EISDIR) { + /* It's a directory - set the file selection box to display it. */ + set_last_open_dir(f_name); + g_free(f_name); + file_selection_set_current_folder(data, last_open_dir); + return; + } + + gtk_entry_set_text(GTK_ENTRY(OBJECT_GET_DATA(win, PRINT_FILE_TE_KEY)), + f_name); + window_destroy(GTK_WIDGET(win)); + + g_free(f_name); +} +#endif + +static void +file_selection_browse_destroy_cb(GtkWidget *win, GtkWidget* parent_te) +{ + GtkWidget *caller; + + /* Get the widget that requested that we be popped up. + (It should arrange to destroy us if it's destroyed, so + that we don't get a pointer to a non-existent window here.) */ + caller = OBJECT_GET_DATA(win, E_FS_CALLER_PTR_KEY); + + /* Tell it we no longer exist. */ + OBJECT_SET_DATA(caller, E_FILE_SEL_DIALOG_PTR_KEY, NULL); + + /* Give the focus to the file text entry widget so the user can just press + Return to print to the file. */ + gtk_widget_grab_focus(parent_te); +} + + +void +set_last_open_dir(char *dirname) +{ + int len; + gchar *new_last_open_dir; + + if (dirname) { + len = strlen(dirname); + if (dirname[len-1] == G_DIR_SEPARATOR) { + new_last_open_dir = g_strconcat(dirname, NULL); + } + else { + new_last_open_dir = g_strconcat(dirname, + G_DIR_SEPARATOR_S, NULL); + } + + if (last_open_dir == NULL || + strcmp(last_open_dir, new_last_open_dir) != 0) + updated_last_open_dir = TRUE; + } + else { + new_last_open_dir = NULL; + if (last_open_dir != NULL) + updated_last_open_dir = TRUE; + } + + if (last_open_dir) { + g_free(last_open_dir); + } + last_open_dir = new_last_open_dir; +} + +char * +get_last_open_dir(void) +{ + return last_open_dir; +} diff --git a/gtk/file_dlg.h b/gtk/file_dlg.h new file mode 100644 index 0000000000..74b1a2fce5 --- /dev/null +++ b/gtk/file_dlg.h @@ -0,0 +1,114 @@ +/* file_utils.h + * Declarations of utilities to use when constructing file selection dialogs + * + * $Id$ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 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. + */ + +/** @defgroup filesel_dialog_group File Selection Dialogs + * + * Dialogs are specially created windows and are related to their parent windows (usually the main window). + * See: @ref howto_window_page for details. + * + * File selection dialogs are created using file_selection_new(). + * + * - "Browse" file_selection_browse() + * - "Open Capture File" file_open_cmd() + * - "Save Capture File As" file_save_as_cmd() + * - "Import Color Filters" file_color_import_cmd_cb() + * - "Export Color Filters" file_color_export_cmd_cb() + * - "Save TCP Follow Stream As" follow_save_as_cmd_cb() + * - "Export Selected Packet Bytes" savehex_cb() + * - "Save Data As CSV" save_csv_as_cb() + * - "Save Payload As ..." on_save_bt_clicked() + * - "Save selected stream in rtpdump" rtpstream_on_save() + * + */ + +/** @file + * Utilities for file selection dialog boxes. Depending on the window + * functions in gui_utils.h, see: @ref howto_window_page for details. + * @ingroup filesel_dialog_group + */ + +#ifndef __FILE_DLG_H__ +#define __FILE_DLG_H__ + +/** the action a file selection is designed for */ +typedef enum { + FILE_SELECTION_OPEN, /**< open a file */ + FILE_SELECTION_READ_BROWSE, /**< browse for a file to read */ + FILE_SELECTION_SAVE, /**< save/export a file */ + FILE_SELECTION_WRITE_BROWSE /**< browse for a file to write to */ +} file_selection_action_t; + +/** Create a file selection dialog box window that belongs to Ethereal's + * main window. See window_new() for usage. + * + * @param title the title for the new file selection dialog + * @param action the desired action + * @return the newly created file selection dialog + */ +extern GtkWidget *file_selection_new(const gchar *title, file_selection_action_t action); + +/** Set the current folder for a file selection dialog. + * + * @param fs the file selection dialog from file_selection_new() + * @param filename the folder to set + * @return TRUE if the folder could be changed successfully + */ +extern gboolean file_selection_set_current_folder(GtkWidget *fs, const gchar *filename); + +/** Set the "extra" widget for a file selection dialog. This is needed to support + * user-supplied options. + * + * @param fs the file selection dialog from file_selection_new() + * @param extra the widget to set + */ +extern void file_selection_set_extra_widget(GtkWidget *fs, GtkWidget *extra); + +/** The function file_selection_browse() will OBJECT_SET_DATA() itself on it's parent window. + * When destroying the parent window, it can close the corresponding file selection. */ +#define E_FILE_SEL_DIALOG_PTR_KEY "file_sel_dialog_ptr" + +/** Browse the files and fill in the associated text entry. + * + * @param file_bt the button that called us (to get the toplevel widget) + * @param file_te the GtkEntry the dialog will have to fill in the filename + * @param title the title for the file selection dialog + * @param action the desired action + */ +extern void +file_selection_browse(GtkWidget *file_bt, GtkWidget *file_te, const char *title, file_selection_action_t action); + +/** Get the latest opened directory. + * + * @return the dirname + */ +extern char *get_last_open_dir(void); + +/** Set the latest opened directory. + * Will already be done when using file_selection_new(). + * + * @param dirname the dirname + */ +extern void set_last_open_dir(char *dirname); + +#endif diff --git a/gtk/follow_dlg.c b/gtk/follow_dlg.c index cb3d0c36b6..cd8389cd07 100644 --- a/gtk/follow_dlg.c +++ b/gtk/follow_dlg.c @@ -46,6 +46,7 @@ #include "follow_dlg.h" #include #include "dlg_utils.h" +#include "file_dlg.h" #include "keys.h" #include "globals.h" #include "main.h" diff --git a/gtk/graph_analysis.c b/gtk/graph_analysis.c index f67c11a2c8..31b0b2c01f 100644 --- a/gtk/graph_analysis.c +++ b/gtk/graph_analysis.c @@ -51,7 +51,10 @@ #include #include "gtkglobals.h" +#if 0 #include "dlg_utils.h" +#endif +#include "file_dlg.h" #include "gui_utils.h" #include "main.h" #include "compat_macros.h" diff --git a/gtk/main.c b/gtk/main.c index b69b4405ca..daa70992eb 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -112,7 +112,10 @@ /* GTK related */ #include "statusbar.h" #include "alert_box.h" +#if 0 #include "dlg_utils.h" +#endif +#include "file_dlg.h" #include "gtkglobals.h" #include "colors.h" #include "gui_utils.h" diff --git a/gtk/print_dlg.c b/gtk/print_dlg.c index 27ba8aff04..bf4964aa6e 100644 --- a/gtk/print_dlg.c +++ b/gtk/print_dlg.c @@ -40,6 +40,7 @@ #include "capture_file_dlg.h" #include "gui_utils.h" #include "dlg_utils.h" +#include "file_dlg.h" #include "main.h" #include #include diff --git a/gtk/print_prefs.c b/gtk/print_prefs.c index a0a8d99217..a90e6ff3ff 100644 --- a/gtk/print_prefs.c +++ b/gtk/print_prefs.c @@ -37,7 +37,10 @@ #include "prefs_dlg.h" #include "util.h" #include "gui_utils.h" +#if 0 #include "dlg_utils.h" +#endif +#include "file_dlg.h" #include "capture_file_dlg.h" #include "compat_macros.h" #include "gtkglobals.h" diff --git a/gtk/proto_draw.c b/gtk/proto_draw.c index d65c48559b..4080946fc6 100644 --- a/gtk/proto_draw.c +++ b/gtk/proto_draw.c @@ -59,7 +59,10 @@ #include "capture_file_dlg.h" #include "proto_draw.h" #include "packet_win.h" +#if 0 #include "dlg_utils.h" +#endif +#include "file_dlg.h" #include "gui_utils.h" #include "gtkglobals.h" #include "compat_macros.h" diff --git a/gtk/recent.c b/gtk/recent.c index 7e7c09ef6d..9da6821050 100644 --- a/gtk/recent.c +++ b/gtk/recent.c @@ -40,7 +40,10 @@ #include #include #include "gui_utils.h" +#if 0 #include "dlg_utils.h" +#endif +#include "file_dlg.h" #include "cfilter_combo_utils.h" #include "simple_dialog.h" #include "file_util.h" diff --git a/gtk/rtp_analysis.c b/gtk/rtp_analysis.c index 48eba899e4..a3b616bf02 100644 --- a/gtk/rtp_analysis.c +++ b/gtk/rtp_analysis.c @@ -65,6 +65,7 @@ #include #include "dlg_utils.h" +#include "file_dlg.h" #include "gui_utils.h" #include "alert_box.h" #include "simple_dialog.h" diff --git a/gtk/rtp_stream_dlg.c b/gtk/rtp_stream_dlg.c index 5c729c6f77..8896e0cac4 100644 --- a/gtk/rtp_stream_dlg.c +++ b/gtk/rtp_stream_dlg.c @@ -39,6 +39,7 @@ #include "../stat_menu.h" #include "gui_stat_menu.h" #include "dlg_utils.h" +#include "file_dlg.h" #include "gui_utils.h" #include "compat_macros.h" #include "gtkglobals.h" diff --git a/gtk/ssl-dlg.c b/gtk/ssl-dlg.c index 1436b1b5ad..8f3034534b 100644 --- a/gtk/ssl-dlg.c +++ b/gtk/ssl-dlg.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3