changeset 13282:a651bfe0a922

[gaim-migrate @ 15648] Part of SF Patch #1175520 from Dennis Nezic with changes by Sadrul to support GTK+ < 2.4 This adds the folder selection function to the request API. committer: Tailor Script <tailor@pidgin.im>
author Richard Laager <rlaager@wiktel.com>
date Tue, 14 Feb 2006 07:45:07 +0000
parents e629076386f1
children 4dcd0fba99a9
files COPYRIGHT src/gtkrequest.c src/request.c src/request.h
diffstat 4 files changed, 120 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/COPYRIGHT	Tue Feb 14 07:28:58 2006 +0000
+++ b/COPYRIGHT	Tue Feb 14 07:45:07 2006 +0000
@@ -185,6 +185,7 @@
 Sergio Moretto
 Christian Muise
 Richard Nelson
+Dennis Nezic
 Matthew A. Nicholson
 Szilard Novaki
 Novell
--- a/src/gtkrequest.c	Tue Feb 14 07:28:58 2006 +0000
+++ b/src/gtkrequest.c	Tue Feb 14 07:45:07 2006 +0000
@@ -1774,7 +1774,7 @@
 	if (id == 1) {
 		if (data->cbs[1] != NULL)
 			((GaimRequestFileCb)data->cbs[1])(data->user_data, data->u.file.name);
-		gaim_request_close(GAIM_REQUEST_FILE, data);
+		gaim_request_close(data->type, data);
 	}
 }
 
@@ -1789,7 +1789,7 @@
 	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);
+		gaim_request_close(data->type, data);
 		return;
 	}
 
@@ -1817,10 +1817,24 @@
 	name = gtk_file_selection_get_filename(GTK_FILE_SELECTION(data->dialog));
 
 	/* If name is a directory then change directories */
-	if (gaim_gtk_check_if_dir(name, GTK_FILE_SELECTION(data->dialog)))
-		return;
+	if (data->type == GAIM_REQUEST_FILE) {
+		if (gaim_gtk_check_if_dir(name, GTK_FILE_SELECTION(data->dialog)))
+			return;
+	}
 
 	current_folder = g_path_get_dirname(name);
+
+	g_free(data->u.file.name);
+	if (data->type == GAIM_REQUEST_FILE)
+		data->u.file.name = g_strdup(name);
+	else
+	{
+		if (g_file_test(name, G_FILE_TEST_IS_DIR))
+			data->u.file.name = g_strdup(name);
+		else
+			data->u.file.name = g_strdup(current_folder);
+	}
+
 	if (current_folder != NULL) {
 		if (data->u.file.savedialog) {
 			gaim_prefs_set_string("/gaim/gtk/filelocations/last_save_folder", current_folder);
@@ -1830,8 +1844,6 @@
 		g_free(current_folder);
 	}
 
-	data->u.file.name = g_strdup(name);
-
 #endif /* FILECHOOSER */
 
 	if ((data->u.file.savedialog == TRUE) &&
@@ -1853,7 +1865,7 @@
 	if (data->cbs[0] != NULL)
 		((GaimRequestFileCb)data->cbs[0])(data->user_data, NULL);
 
-	gaim_request_close(GAIM_REQUEST_FILE, data);
+	gaim_request_close(data->type, data);
 }
 #endif /* FILECHOOSER */
 
@@ -1951,6 +1963,57 @@
 	return (void *)data;
 }
 
+static void *
+gaim_gtk_request_folder(const char *title, const char *dirname,
+					  GCallback ok_cb, GCallback cancel_cb,
+					  void *user_data)
+{
+	GaimGtkRequestData *data;
+	GtkWidget *dirsel;
+	
+	data = g_new0(GaimGtkRequestData, 1);
+	data->type = GAIM_REQUEST_FOLDER;
+	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 = FALSE;
+	
+#if GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */
+	/* Use a translated "Select Folder..." in place of NULL after strings thaw. */
+	dirsel = gtk_file_chooser_dialog_new(
+						title ? title : NULL,
+						NULL,
+						GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+						GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+						GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+						NULL);
+	gtk_dialog_set_default_response(GTK_DIALOG(dirsel), GTK_RESPONSE_ACCEPT);
+
+	if ((dirname != NULL) && (*dirname != '\0'))
+		gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dirsel), dirname);
+
+	g_signal_connect(G_OBJECT(GTK_FILE_CHOOSER(dirsel)), "response",
+						G_CALLBACK(file_ok_check_if_exists_cb), data);
+#else
+	/* Use a translated "Select Folder..." in place of NULL after strings thaw. */
+	dirsel = gtk_file_selection_new(title ? title : NULL);
+
+	g_signal_connect_swapped(G_OBJECT(dirsel), "delete_event",
+							 G_CALLBACK(file_cancel_cb), data);
+	g_signal_connect_swapped(G_OBJECT(GTK_FILE_SELECTION(dirsel)->cancel_button),
+					 "clicked", G_CALLBACK(file_cancel_cb), data);
+	g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(dirsel)->ok_button), "clicked",
+					 G_CALLBACK(file_ok_check_if_exists_cb), data);
+#endif
+
+	data->dialog = dirsel;
+	gtk_widget_show(dirsel);
+
+	return (void *)data;
+}
+
 static void
 gaim_gtk_close_request(GaimRequestType type, void *ui_handle)
 {
@@ -1976,7 +2039,8 @@
 	gaim_gtk_request_action,
 	gaim_gtk_request_fields,
 	gaim_gtk_request_file,
-	gaim_gtk_close_request
+	gaim_gtk_close_request,
+	gaim_gtk_request_folder
 };
 
 GaimRequestUiOps *
--- a/src/request.c	Tue Feb 14 07:28:58 2006 +0000
+++ b/src/request.c	Tue Feb 14 07:45:07 2006 +0000
@@ -1363,6 +1363,29 @@
 	return NULL;
 }
 
+void *
+gaim_request_folder(void *handle, const char *title, const char *dirname,
+				  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_FOLDER;
+		info->handle    = handle;
+		info->ui_handle = ops->request_folder(title, dirname,
+											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)
 {
--- a/src/request.h	Tue Feb 14 07:28:58 2006 +0000
+++ b/src/request.h	Tue Feb 14 07:45:07 2006 +0000
@@ -42,7 +42,8 @@
 	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. */
+	GAIM_REQUEST_FILE,       /**< File open or save request. */
+	GAIM_REQUEST_FOLDER      /**< Folder selection request.  */
 
 } GaimRequestType;
 
@@ -205,6 +206,9 @@
 						  gboolean savedialog, GCallback ok_cb,
 						  GCallback cancel_cb, void *user_data);
 	void (*close_request)(GaimRequestType type, void *ui_handle);
+	void *(*request_folder)(const char *title, const char *dirname,
+						  GCallback ok_cb, GCallback cancel_cb,
+						  void *user_data);
 } GaimRequestUiOps;
 
 typedef void (*GaimRequestInputCb)(void *, const char *);
@@ -1371,6 +1375,25 @@
 						GCallback ok_cb, GCallback cancel_cb,
 						void *user_data);
 
+/**
+ * Displays a folder select dialog. Returns the selected filename to
+ * the callback.
+ *
+ * @param handle      The plugin or connection handle.  For some
+ *                    things this is EXTREMELY important.  See
+ *                    the comments on gaim_request_input.
+ * @param title       The title for the dialog (may be @c NULL)
+ * @param dirname     The default directory name (may be @c NULL)
+ * @param ok_cb       The callback for the @c OK button.
+ * @param cancel_cb   The callback for the @c Cancel button.
+ * @param user_data   The data to pass to the callback.
+ *
+ * @return A UI-specific handle.
+ */
+void *gaim_request_folder(void *handle, const char *title, const char *dirname,
+						GCallback ok_cb, GCallback cancel_cb,
+						void *user_data);
+
 /*@}*/
 
 /**************************************************************************/