changeset 9502:578986136bac

[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 <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Sat, 10 Jul 2004 18:38:20 +0000
parents d95e134da0ac
children d822b19b751c
files src/gtkdebug.c src/gtkrequest.c src/protocols/silc/buddy.c src/protocols/silc/chat.c src/request.c src/request.h
diffstat 6 files changed, 190 insertions(+), 229 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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,
--- 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);
 }
--- 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;
--- 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)
 {
--- 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                                               */