# HG changeset patch # User Mark Doliner # Date 1089484700 0 # Node ID 578986136bac3b6a4ad3cb08163bbe1156379638 # Parent d95e134da0ac55045002ff9a443fb17a749062c5 [gaim-migrate @ 10329] Make gaim_request_file support saving files as well as opening files. Changed silc appropriately, and made the Save dialog in the debug window use this. I changed request.c so that, when closing a request window, it also tries to change any requests or notifies that were created using the ui_handle as the handle. It's similar to using "gc" as the first parameter of a gaim_request_bleh or gaim_notify_bleh function. committer: Tailor Script diff -r d95e134da0ac -r 578986136bac src/gtkdebug.c --- a/src/gtkdebug.c Sat Jul 10 16:45:36 2004 +0000 +++ b/src/gtkdebug.c Sat Jul 10 18:38:20 2004 +0000 @@ -43,7 +43,6 @@ GtkWidget *window; GtkWidget *text; GtkWidget *find; - GtkWidget *save; gboolean timestamps; gboolean paused; @@ -73,11 +72,9 @@ { if (debug_win->timestamps_handle != 0) gaim_prefs_disconnect_callback(debug_win->timestamps_handle); - if (debug_win->save != NULL) { - gaim_notify_close_with_handle(debug_win->save); - gaim_request_close_with_handle(debug_win->save); - gtk_widget_destroy(debug_win->save); - } + + /* If the "Save Log" dialog is open then close it */ + gaim_request_close_with_handle(debug_win); g_free(debug_win); debug_win = NULL; @@ -175,27 +172,14 @@ } static void -save_writefile_cb(DebugWindow *win, gint id) +save_writefile_cb(void *user_data, const char *filename) { - const char *filename; + DebugWindow *win = (DebugWindow *)user_data; FILE *fp; char *tmp; -#if GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ - filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(win->save)); -#else /* FILECHOOSER */ - filename = gtk_file_selection_get_filename(GTK_FILE_SELECTION(win->save)); -#endif /* FILECHOOSER */ - - gaim_notify_close_with_handle(win->save); - - if (filename == NULL) { - gaim_notify_error(win->save, NULL, _("Invalid file name."), NULL); - return; - } - if ((fp = fopen(filename, "w+")) == NULL) { - gaim_notify_error(win->save, NULL, _("Unable to open file."), NULL); + gaim_notify_error(win, NULL, _("Unable to open file."), NULL); return; } @@ -205,97 +189,14 @@ g_free(tmp); fclose(fp); - - gtk_widget_destroy(win->save); - win->save = NULL; } -#if GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ -static void -save_checkfile_cb(GtkWidget *widget, gint response, DebugWindow *win) -{ - const char *filename; - - if (response != GTK_RESPONSE_ACCEPT) { - gaim_notify_close_with_handle(win->save); - gaim_request_close_with_handle(win->save); - if (response == GTK_RESPONSE_CANCEL) - gtk_widget_destroy(win->save); - win->save = NULL; - return; - } - - filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(win->save)); -#else /* FILECHOOSER */ -static void -save_checkfile_cb(GtkWidget *widget, DebugWindow *win) -{ - const char *filename; - - filename = gtk_file_selection_get_filename(GTK_FILE_SELECTION(win->save)); - if (gaim_gtk_check_if_dir(filename, GTK_FILE_SELECTION(win->save))) { - /* Descend into directory? */ - return; - } -#endif /* FILECHOOSER */ - - gaim_request_close_with_handle(win->save); - - if (g_file_test(filename, G_FILE_TEST_EXISTS)) - { - gaim_request_yes_no(win->save, NULL, _("That file already exists"), - _("Would you like to overwrite it?"), 1, - win, G_CALLBACK(save_writefile_cb), NULL); - } - else - save_writefile_cb(win, 1); -} - -#if !GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ -static void -save_destroy_cb(GtkWidget *widget, DebugWindow *win) -{ - if (win->save != NULL) { - gaim_notify_close_with_handle(win->save); - gaim_request_close_with_handle(win->save); - gtk_widget_destroy(win->save); - win->save = NULL; - } -} -#endif - static void save_cb(GtkWidget *w, DebugWindow *win) { - if (win->save != NULL) { - gtk_window_present(GTK_WINDOW(win->save)); - return; - } - -#if GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ - win->save = gtk_file_chooser_dialog_new(_("Save Conversation"), - GTK_WINDOW(win->window), - GTK_FILE_CHOOSER_ACTION_SAVE, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, - NULL); - gtk_dialog_set_default_response(GTK_DIALOG(win->save), GTK_RESPONSE_ACCEPT); - gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(win->save), - "gaim-debug.log"); - g_signal_connect(G_OBJECT(win->save), "response", - G_CALLBACK(save_checkfile_cb), win); -#else /* FILECHOOSER */ - win->save = gtk_file_selection_new(_("Save Debug Log")); - gtk_file_selection_set_filename(GTK_FILE_SELECTION(win->save), "gaim-debug.log"); - g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(win->save)->ok_button), - "clicked", G_CALLBACK(save_checkfile_cb), win); - g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(win->save)->cancel_button), - "clicked", G_CALLBACK(save_destroy_cb), win); - g_signal_connect(G_OBJECT(win->save), - "destroy", G_CALLBACK(save_destroy_cb), win); -#endif /* FILECHOOSER */ - - gtk_widget_show_all(GTK_WIDGET(win->save)); + gaim_request_close_with_handle(win); + gaim_request_file(win, _("Save Debug Log"), "gaim-debug.log", TRUE, + G_CALLBACK(save_writefile_cb), NULL, win); } static void diff -r d95e134da0ac -r 578986136bac src/gtkrequest.c --- a/src/gtkrequest.c Sat Jul 10 16:45:36 2004 +0000 +++ b/src/gtkrequest.c Sat Jul 10 18:38:20 2004 +0000 @@ -68,6 +68,13 @@ } multifield; + struct + { + gboolean savedialog; + gchar *name; + + } file; + } u; } GaimGtkRequestData; @@ -1344,6 +1351,119 @@ } static void +file_yes_no_cb(GaimGtkRequestData *data, gint id) +{ + if (data->cbs[id] != NULL) + ((GaimRequestFileCb)data->cbs[id])(data->user_data, data->u.file.name); + g_free(data->u.file.name); + + if (id == 1) + gaim_request_close(GAIM_REQUEST_FILE, data); +} + +static void +#if GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ +file_ok_check_if_exists_cb(GtkWidget *widget, gint response, GaimGtkRequestData *data) +{ + if (response != GTK_RESPONSE_ACCEPT) { + if (data->cbs[0] != NULL) + ((GaimRequestFileCb)data->cbs[0])(data->user_data, NULL); + gaim_request_close(GAIM_REQUEST_FILE, data); + return; + } + + data->u.file.name = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(data->dialog)); +#else /* FILECHOOSER */ +file_ok_check_if_exists_cb(GtkWidget *button, GaimGtkRequestData *data) +{ + gchar *name; + + name = gtk_file_selection_get_filename(GTK_FILE_SELECTION(data->dialog))); + if (gaim_gtk_check_if_dir(name, GTK_FILE_SELECTION(data->dialog))) + /* Descend into directory? */ + /* Close dialog? */ + return; + data->u.file.name = name; +#endif /* FILECHOOSER */ + + if ((data->u.file.savedialog == TRUE) && + (g_file_test(data->u.file.name, G_FILE_TEST_EXISTS))) { + gaim_request_yes_no(data, NULL, _("That file already exists"), + _("Would you like to overwrite it?"), 1, data, + G_CALLBACK(file_yes_no_cb), + G_CALLBACK(file_yes_no_cb)); + } else + file_yes_no_cb(data, 1); +} + +#if !GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ +static void +file_cancel_cb(GtkWidget *widget, GaimGtkRequestData *data) +{ + if (data->cbs[0] != NULL) + ((GaimRequestFileCb)data->cbs[0])(data->user_data, NULL); + + gaim_request_close(GAIM_REQUEST_FILE, data); +} +#endif /* FILECHOOSER */ + +static void * +gaim_gtk_request_file(const char *title, const char *filename, + gboolean savedialog, + GCallback ok_cb, GCallback cancel_cb, + void *user_data) +{ + GaimGtkRequestData *data; + GtkWidget *filesel; + + data = g_new0(GaimGtkRequestData, 1); + data->type = GAIM_REQUEST_FILE; + data->user_data = user_data; + data->cb_count = 2; + data->cbs = g_new0(GCallback, 2); + data->cbs[0] = cancel_cb; + data->cbs[1] = ok_cb; + data->u.file.savedialog = savedialog; + +#if GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ + filesel = gtk_file_chooser_dialog_new( + title ? title : (savedialog ? _("Save File...") + : _("Open File...")), + NULL, + savedialog ? GTK_FILE_CHOOSER_ACTION_SAVE + : GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + savedialog ? GTK_STOCK_SAVE + : GTK_STOCK_OPEN, + GTK_RESPONSE_ACCEPT, + NULL); + gtk_dialog_set_default_response(GTK_DIALOG(filesel), GTK_RESPONSE_ACCEPT); + if (filename != NULL) { + if (savedialog) + gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(filesel), filename); + else + gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(filesel), filename); + } + g_signal_connect(G_OBJECT(GTK_FILE_CHOOSER(filesel)), "response", + G_CALLBACK(file_ok_check_if_exists_cb), data); +#else /* FILECHOOSER */ + filesel = gtk_file_selection_new(title ? title : ""); + gtk_file_selection_set_filename(GTK_FILE_SELECTION(filesel), filename); + g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(filesel)), "delete_event", + G_CALLBACK(file_cancel_cb), data); + g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(filesel)->cancel_button), + "clicked", G_CALLBACK(file_cancel_cb), data); + g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(filesel)->ok_button), + "clicked", G_CALLBACK(file_ok_check_if_exists_cb), data); +#endif /* FILECHOOSER */ + + data->dialog = filesel; + gtk_widget_show(filesel); + + return (void *)data; +} + +static void gaim_gtk_close_request(GaimRequestType type, void *ui_handle) { GaimGtkRequestData *data = (GaimGtkRequestData *)ui_handle; @@ -1359,70 +1479,6 @@ g_free(data); } -static void -file_ok_cb(GtkWidget *button, GaimGtkRequestData *data) -{ - const char *name; - - if (!GTK_WIDGET_HAS_FOCUS(button)) - gtk_widget_grab_focus(button); - - if (data->cbs[0] != NULL) { - name = gtk_file_selection_get_filename(GTK_FILE_SELECTION(data->dialog)); - if (gaim_gtk_check_if_dir(name, GTK_FILE_SELECTION(data->dialog))) - name = NULL; - - ((GaimRequestInputCb)data->cbs[0])(data->user_data, name); - } - - gaim_request_close(GAIM_REQUEST_INPUT, data); -} - -static void -file_cancel_cb(GtkWidget *button, GaimGtkRequestData *data) -{ - if (data->cbs[1] != NULL) - ((GaimRequestInputCb)data->cbs[1])(data->user_data, NULL); - - gaim_request_close(GAIM_REQUEST_INPUT, data); -} - -static void * -gaim_gtk_request_file(const char *title, const char *filename, - GCallback ok_cb, GCallback cancel_cb, - void *user_data) -{ - GaimGtkRequestData *data; - GtkWidget *filesel; - char *cur_dir, *init_str, tmp[512]; - - data = g_new0(GaimGtkRequestData, 1); - data->type = GAIM_REQUEST_INPUT; - data->user_data = user_data; - data->cb_count = 2; - data->cbs = g_new0(GCallback, 2); - data->cbs[0] = ok_cb; - data->cbs[1] = cancel_cb; - - filesel = gtk_file_selection_new(title ? title : ""); - cur_dir = g_get_current_dir(); - g_snprintf(tmp, sizeof(tmp), "%s" G_DIR_SEPARATOR_S, cur_dir); - init_str = g_build_filename(tmp, filename, NULL); - gtk_file_selection_set_filename(GTK_FILE_SELECTION(filesel), init_str); - g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(filesel)), - "delete_event", G_CALLBACK(file_cancel_cb), data); - g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(filesel)->cancel_button), - "clicked", G_CALLBACK(file_cancel_cb), data); - g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(filesel)->ok_button), - "clicked", G_CALLBACK(file_ok_cb), data); - gtk_widget_show(filesel); - g_free(cur_dir); - g_free(init_str); - - data->dialog = filesel; - return (void *)data; -} - static GaimRequestUiOps ops = { gaim_gtk_request_input, diff -r d95e134da0ac -r 578986136bac src/protocols/silc/buddy.c --- a/src/protocols/silc/buddy.c Sat Jul 10 16:45:36 2004 +0000 +++ b/src/protocols/silc/buddy.c Sat Jul 10 18:38:20 2004 +0000 @@ -1020,7 +1020,7 @@ } /* Open file selector to select the public key. */ - gaim_request_file(NULL, _("Open..."), NULL, + gaim_request_file(NULL, _("Open..."), NULL, FALSE, G_CALLBACK(silcgaim_add_buddy_ask_import), G_CALLBACK(silcgaim_add_buddy_ask_pk_cancel), r); } diff -r d95e134da0ac -r 578986136bac src/protocols/silc/chat.c --- a/src/protocols/silc/chat.c Sat Jul 10 16:45:36 2004 +0000 +++ b/src/protocols/silc/chat.c Sat Jul 10 18:38:20 2004 +0000 @@ -273,7 +273,7 @@ f = gaim_request_fields_get_field(fields, "list"); if (!gaim_request_field_list_get_selected(f)) { /* Add new public key */ - gaim_request_file(NULL, _("Open Public Key..."), "", + gaim_request_file(NULL, _("Open Public Key..."), NULL, FALSE, G_CALLBACK(silcgaim_chat_chpk_add), G_CALLBACK(silcgaim_chat_chpk_cancel), sgc); return; diff -r d95e134da0ac -r 578986136bac src/request.c --- a/src/request.c Sat Jul 10 16:45:36 2004 +0000 +++ b/src/request.c Sat Jul 10 18:38:20 2004 +0000 @@ -22,6 +22,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "notify.h" #include "request.h" #include "debug.h" @@ -1278,27 +1279,59 @@ return NULL; } +void * +gaim_request_file(void *handle, const char *title, const char *filename, + gboolean savedialog, + GCallback ok_cb, GCallback cancel_cb, void *user_data) +{ + GaimRequestUiOps *ops; + + ops = gaim_request_get_ui_ops(); + + if (ops != NULL && ops->request_file != NULL) { + GaimRequestInfo *info; + + info = g_new0(GaimRequestInfo, 1); + info->type = GAIM_REQUEST_FILE; + info->handle = handle; + info->ui_handle = ops->request_file(title, filename, savedialog, + ok_cb, cancel_cb, user_data); + handles = g_list_append(handles, info); + return info->ui_handle; + } + + return NULL; +} + +static void +gaim_request_close_info(GaimRequestInfo *info) +{ + GaimRequestUiOps *ops; + + ops = gaim_request_get_ui_ops(); + + gaim_notify_close_with_handle(info->ui_handle); + gaim_request_close_with_handle(info->ui_handle); + + if (ops != NULL && ops->close_request != NULL) + ops->close_request(info->type, info->ui_handle); + + g_free(info); +} + void gaim_request_close(GaimRequestType type, void *ui_handle) { GList *l; - GaimRequestUiOps *ops; g_return_if_fail(ui_handle != NULL); - ops = gaim_request_get_ui_ops(); - for (l = handles; l != NULL; l = l->next) { GaimRequestInfo *info = l->data; if (info->ui_handle == ui_handle) { handles = g_list_remove(handles, info); - - if (ops != NULL && ops->close_request != NULL) - ops->close_request(info->type, ui_handle); - - g_free(info); - + gaim_request_close_info(info); break; } } @@ -1308,12 +1341,9 @@ gaim_request_close_with_handle(void *handle) { GList *l, *l_next; - GaimRequestUiOps *ops; g_return_if_fail(handle != NULL); - ops = gaim_request_get_ui_ops(); - for (l = handles; l != NULL; l = l_next) { GaimRequestInfo *info = l->data; @@ -1321,40 +1351,11 @@ if (info->handle == handle) { handles = g_list_remove(handles, info); - - if (ops != NULL && ops->close_request != NULL) - ops->close_request(info->type, info->ui_handle); - - g_free(info); + gaim_request_close_info(info); } } } -void * -gaim_request_file(void *handle, - const char *title, const char *filename, - GCallback ok_cb, GCallback cancel_cb, - void *user_data) -{ - GaimRequestUiOps *ops; - - ops = gaim_request_get_ui_ops(); - - if (ops != NULL && ops->request_file != NULL) { - GaimRequestInfo *info; - - info = g_new0(GaimRequestInfo, 1); - info->type = GAIM_REQUEST_INPUT; - info->handle = handle; - info->ui_handle = ops->request_file(title, filename, - ok_cb, cancel_cb, user_data); - handles = g_list_append(handles, info); - return info->ui_handle; - } - - return NULL; -} - void gaim_request_set_ui_ops(GaimRequestUiOps *ops) { diff -r d95e134da0ac -r 578986136bac src/request.h --- a/src/request.h Sat Jul 10 16:45:36 2004 +0000 +++ b/src/request.h Sat Jul 10 18:38:20 2004 +0000 @@ -36,10 +36,11 @@ */ typedef enum { - GAIM_REQUEST_INPUT = 0, /**< Text input request. */ - GAIM_REQUEST_CHOICE, /**< Multiple-choice request. */ - GAIM_REQUEST_ACTION, /**< Action request. */ - GAIM_REQUEST_FIELDS /**< Multiple fields request. */ + GAIM_REQUEST_INPUT = 0, /**< Text input request. */ + GAIM_REQUEST_CHOICE, /**< Multiple-choice request. */ + GAIM_REQUEST_ACTION, /**< Action request. */ + GAIM_REQUEST_FIELDS, /**< Multiple fields request. */ + GAIM_REQUEST_FILE /**< File open or save request. */ } GaimRequestType; @@ -190,16 +191,16 @@ const char *ok_text, GCallback ok_cb, const char *cancel_text, GCallback cancel_cb, void *user_data); - void *(*request_file)(const char *title, const char *filename, - GCallback ok_cb, GCallback cancel_cb, - void *user_data); + gboolean savedialog, GCallback ok_cb, + GCallback cancel_cb, void *user_data); void (*close_request)(GaimRequestType type, void *ui_handle); } GaimRequestUiOps; typedef void (*GaimRequestInputCb)(void *, const char *); typedef void (*GaimRequestActionCb)(void *, int); typedef void (*GaimRequestFieldsCb)(void *, GaimRequestFields *fields); +typedef void (*GaimRequestFileCb)(void *, const char *filename); #ifdef __cplusplus extern "C" { @@ -1251,15 +1252,15 @@ (default_action), (user_data), 2, \ _("Accept"), (accept_cb), _("Cancel"), (cancel_cb)) -/*@}*/ - /** - * Displays file selector request dialog. Returns the selected filename into - * the callback. + * Displays a file selector request dialog. Returns the selected filename into + * the callback. Can be used for either opening a file or saving a file. * * @param handle The plugin or connection handle. * @param title The title for the dialog (may be NULL) * @param filename The default filename (may be NULL) + * @param savedialog True if this dialog is being used to save a file. + * False if it is being used to open a file. * @param ok_cb The callback for the OK button. * @param cancel_cb The callback for the cancel button. * @param user_data The data to pass to the callback. @@ -1267,9 +1268,11 @@ * @return A UI-specific handle. */ void *gaim_request_file(void *handle, const char *title, const char *filename, - GCallback ok_cb, GCallback cancel_cb, - void *user_data); + gboolean savedialog, + GCallback ok_cb, GCallback cancel_cb, + void *user_data); +/*@}*/ /**************************************************************************/ /** @name UI Operations API */