[empathy: 1/17] Implementing drag and drop file sending on chat windows



commit 2e2fdd45ae2d7fac58c9cc40b48c84ffc6b3f48e
Author: Shaun McCance <Shaun McCance>
Date:   Mon Sep 14 21:15:06 2009 -0500

    Implementing drag and drop file sending on chat windows

 libempathy-gtk/empathy-chat.c     |    1 +
 libempathy-gtk/empathy-ui-utils.c |   36 +++++++++++++++++++-----------
 libempathy-gtk/empathy-ui-utils.h |    2 +
 src/empathy-chat-window.c         |   44 +++++++++++++++++++++++++++++++++++++
 4 files changed, 70 insertions(+), 13 deletions(-)
---
diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c
index 372e90c..c83649a 100644
--- a/libempathy-gtk/empathy-chat.c
+++ b/libempathy-gtk/empathy-chat.c
@@ -2007,6 +2007,7 @@ chat_create_ui (EmpathyChat *chat)
 
 	/* Add message view. */
 	chat->view = empathy_theme_manager_create_view (empathy_theme_manager_get ());
+	gtk_drag_dest_unset (GTK_WIDGET (chat->view));
 	g_signal_connect (chat->view, "focus_in_event",
 			  G_CALLBACK (chat_text_view_focus_in_event_cb),
 			  chat);
diff --git a/libempathy-gtk/empathy-ui-utils.c b/libempathy-gtk/empathy-ui-utils.c
index ce5ec41..411a766 100644
--- a/libempathy-gtk/empathy-ui-utils.c
+++ b/libempathy-gtk/empathy-ui-utils.c
@@ -1451,30 +1451,40 @@ empathy_toggle_button_set_state_quietly (GtkWidget *widget,
 	g_signal_handlers_unblock_by_func (widget, callback, user_data);
 }
 
+void
+empathy_send_file (EmpathyContact *contact, GFile *file)
+{
+	EmpathyFTFactory *factory;
+	GtkRecentManager *manager;
+	gchar *uri;
+
+	g_return_if_fail (EMPATHY_IS_CONTACT (contact));
+	g_return_if_fail (G_IS_FILE (file));
+
+	factory = empathy_ft_factory_dup_singleton ();
+
+	empathy_ft_factory_new_transfer_outgoing (factory, contact, file);
+
+	uri = g_file_get_uri (file);
+	manager = gtk_recent_manager_get_default ();
+	gtk_recent_manager_add_item (manager, uri);
+	g_free (uri);
+
+	g_object_unref (factory);
+}
+
 static void
 file_manager_send_file_response_cb (GtkDialog      *widget,
 				    gint            response_id,
 				    EmpathyContact *contact)
 {
-	EmpathyFTFactory *factory;
 	GFile *file;
-	gchar *uri;
-	GtkRecentManager *manager;
 
 	if (response_id == GTK_RESPONSE_OK) {
 		file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (widget));
-		uri = g_file_get_uri (file);
-
-		factory = empathy_ft_factory_dup_singleton ();
 
-		empathy_ft_factory_new_transfer_outgoing (factory, contact,
-		                                          file);
+		empathy_send_file (contact, file);
 
-		manager = gtk_recent_manager_get_default ();
-		gtk_recent_manager_add_item (manager, uri);
-
-		g_free (uri);
-		g_object_unref (factory);
 		g_object_unref (file);
 	}
 
diff --git a/libempathy-gtk/empathy-ui-utils.h b/libempathy-gtk/empathy-ui-utils.h
index 7bec088..0f453dd 100644
--- a/libempathy-gtk/empathy-ui-utils.h
+++ b/libempathy-gtk/empathy-ui-utils.h
@@ -110,6 +110,8 @@ void        empathy_toggle_button_set_state_quietly     (GtkWidget        *widge
 GtkWidget * empathy_link_button_new                     (const gchar      *url,
 							 const gchar      *title);
 
+void        empathy_send_file                           (EmpathyContact   *contact,
+							 GFile            *file);
 void        empathy_send_file_with_file_chooser         (EmpathyContact   *contact);
 void        empathy_receive_file_with_file_chooser      (EmpathyFTHandler *handler);
 
diff --git a/src/empathy-chat-window.c b/src/empathy-chat-window.c
index 278c8f0..15ab92c 100644
--- a/src/empathy-chat-window.c
+++ b/src/empathy-chat-window.c
@@ -106,6 +106,7 @@ static const guint tab_accel_keys[] = {
 
 typedef enum {
 	DND_DRAG_TYPE_CONTACT_ID,
+	DND_DRAG_TYPE_URI_LIST,
 	DND_DRAG_TYPE_TAB
 } DndDragType;
 
@@ -114,6 +115,10 @@ static const GtkTargetEntry drag_types_dest[] = {
 	{ "GTK_NOTEBOOK_TAB", GTK_TARGET_SAME_APP, DND_DRAG_TYPE_TAB },
 };
 
+static const GtkTargetEntry drag_types_uri_dest[] = {
+	{ "text/uri-list", 0, DND_DRAG_TYPE_URI_LIST },
+};
+
 static void chat_window_update (EmpathyChatWindow *window);
 
 G_DEFINE_TYPE (EmpathyChatWindow, empathy_chat_window, G_TYPE_OBJECT);
@@ -1403,6 +1408,40 @@ chat_window_drag_data_received (GtkWidget        *widget,
 		 */
 		gtk_drag_finish (context, TRUE, FALSE, time_);
 	}
+	else if (info == DND_DRAG_TYPE_URI_LIST) {
+		EmpathyChatWindowPriv *priv;
+		EmpathyContact *contact;
+		const gchar *data;
+		GFile *file;
+		gchar *nl;
+		gchar *uri;
+
+		/* Only handle a single file for new.  It would be wicked cool to be
+		   able to do multiple files, offering to zip them or whatever like
+		   nautilus-sendto does.  Note that text/uri-list is defined to have
+		   each line terminated by \r\n, but we can be tolerant of applications
+		   that only use \n or don't terminate single-line entries.
+		 */
+		data = (const gchar*) gtk_selection_data_get_data (selection);
+		nl = strstr (data, "\r\n");
+		if (!nl) {
+			nl = strchr (data, '\n');
+		}
+		if (nl) {
+			uri = g_strndup (data, nl - data);
+			file = g_file_new_for_uri (uri);
+			g_free (uri);
+		}
+		else {
+			file = g_file_new_for_uri (data);
+		}
+
+		priv = GET_PRIV (window);
+		contact = empathy_chat_get_remote_contact (priv->current_chat);
+		empathy_send_file (contact, file);
+
+		g_object_unref (file);
+	}
 	else if (info == DND_DRAG_TYPE_TAB) {
 		EmpathyChat        **chat;
 		EmpathyChatWindow   *old_window = NULL;
@@ -1617,6 +1656,11 @@ empathy_chat_window_init (EmpathyChatWindow *window)
 			   drag_types_dest,
 			   G_N_ELEMENTS (drag_types_dest),
 			   GDK_ACTION_MOVE);
+	gtk_drag_dest_set (GTK_WIDGET (priv->notebook),
+			   GTK_DEST_DEFAULT_ALL,
+			   drag_types_uri_dest,
+			   G_N_ELEMENTS (drag_types_uri_dest),
+			   GDK_ACTION_COPY);
 
 	g_signal_connect (priv->notebook,
 			  "drag-data-received",



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]