]> git.0d.be Git - empathy.git/commitdiff
Implementing drag and drop file sending on chat windows
authorShaun McCance <Shaun McCance>
Tue, 15 Sep 2009 02:15:06 +0000 (21:15 -0500)
committerShaun McCance <shaunm@gnome.org>
Tue, 24 Nov 2009 18:05:31 +0000 (12:05 -0600)
libempathy-gtk/empathy-chat.c
libempathy-gtk/empathy-ui-utils.c
libempathy-gtk/empathy-ui-utils.h
src/empathy-chat-window.c

index 372e90cf034a8ab9d64762d6e254d7a030f3b7f0..c83649a047df6f76721adcfee91d0ad493d1fa26 100644 (file)
@@ -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);
index ce5ec419e8ab6a0cc4dbf165bb7ad23254496447..411a7664031f264ac560fb2727aa729b68b2f270 100644 (file)
@@ -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);
        }
 
index 7bec0884e9e9f46990e5c3d6f875d1af2046a6c3..0f453ddbce3e39c0e28ad6d84c33c467ae36189a 100644 (file)
@@ -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);
 
index 278c8f044e3ceca946dc9835b91060ec80fd7b0f..15ab92ce668733c8e3cf729e8447d9bf1575c37f 100644 (file)
@@ -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",