[evolution] Composer - Fix more drag and drop related bugs



commit 75e63db31a8da3b5ac85463f6b18c970171fed88
Author: Tomas Popela <tpopela redhat com>
Date:   Thu Feb 12 13:27:56 2015 +0100

    Composer - Fix more drag and drop related bugs
    
    This fixes the following bugs:
    - DnD inside the view was still copying things not moving them
    - Prevent WebKit to insert the URI inside the view when DnD'ing some
      file inside the view
    - DnD'ed inline image was inserted on the caret position and not on the
      position we dropped it.

 composer/e-composer-private.c |    2 +-
 composer/e-composer-private.h |    2 +-
 composer/e-msg-composer.c     |  128 ++++++++++++++++++++++++-----------------
 3 files changed, 78 insertions(+), 54 deletions(-)
---
diff --git a/composer/e-composer-private.c b/composer/e-composer-private.c
index 771dc4e..0083e79 100644
--- a/composer/e-composer-private.c
+++ b/composer/e-composer-private.c
@@ -137,7 +137,7 @@ e_composer_private_constructed (EMsgComposer *composer)
        priv->busy = FALSE;
        priv->saved_editable = FALSE;
        priv->drop_occured = FALSE;
-       priv->remove_inserted_uri_on_drop = FALSE;
+       priv->dnd_is_uri = FALSE;
 
        priv->focused_entry = NULL;
 
diff --git a/composer/e-composer-private.h b/composer/e-composer-private.h
index 69ebd90..7f798b4 100644
--- a/composer/e-composer-private.h
+++ b/composer/e-composer-private.h
@@ -101,7 +101,7 @@ struct _EMsgComposerPrivate {
        gboolean saved_editable;
        gboolean set_signature_from_message;
        gboolean drop_occured;
-       gboolean remove_inserted_uri_on_drop;
+       gboolean dnd_is_uri;
 
        gint focused_entry_selection_start;
        gint focused_entry_selection_end;
diff --git a/composer/e-msg-composer.c b/composer/e-msg-composer.c
index 99e12ad..9a110ae 100644
--- a/composer/e-msg-composer.c
+++ b/composer/e-msg-composer.c
@@ -110,7 +110,8 @@ enum DndTargetType {
        DND_TARGET_TYPE_TEXT_HTML,
        DND_TARGET_TYPE_UTF8_STRING,
        DND_TARGET_TYPE_TEXT_PLAIN,
-       DND_TARGET_TYPE_STRING
+       DND_TARGET_TYPE_STRING,
+       DND_TARGET_TYPE_TEXT_PLAIN_UTF8
 };
 
 static GtkTargetEntry drag_dest_targets[] = {
@@ -120,6 +121,7 @@ static GtkTargetEntry drag_dest_targets[] = {
        { (gchar *) "UTF8_STRING", 0, DND_TARGET_TYPE_UTF8_STRING },
        { (gchar *) "text/plain", 0, DND_TARGET_TYPE_TEXT_PLAIN },
        { (gchar *) "STRING", 0, DND_TARGET_TYPE_STRING },
+       { (gchar *) "text/plain;charset=utf-8", 0, DND_TARGET_TYPE_TEXT_PLAIN_UTF8 },
 };
 
 static guint signals[LAST_SIGNAL];
@@ -1763,31 +1765,6 @@ msg_composer_drag_motion_cb (GtkWidget *widget,
        return FALSE;
 }
 
-static gchar *
-next_uri (guchar **uri_list,
-          gint *len,
-          gint *list_len)
-{
-       guchar *uri, *begin;
-
-       begin = *uri_list;
-       *len = 0;
-       while (**uri_list && **uri_list != '\n' && **uri_list != '\r' && *list_len) {
-               (*uri_list) ++;
-               (*len) ++;
-               (*list_len) --;
-       }
-
-       uri = (guchar *) g_strndup ((gchar *) begin, *len);
-
-       while ((!**uri_list || **uri_list == '\n' || **uri_list == '\r') && *list_len) {
-               (*uri_list) ++;
-               (*list_len) --;
-       }
-
-       return (gchar *) uri;
-}
-
 static gboolean
 msg_composer_drag_drop_cb (GtkWidget *widget,
                            GdkDragContext *context,
@@ -1814,6 +1791,12 @@ msg_composer_drag_drop_cb (GtkWidget *widget,
        if (target == GDK_NONE)
                gdk_drag_status (context, 0, time);
        else {
+               /* Prevent WebKit from pasting the URI of file into the view. */
+               if (composer->priv->dnd_is_uri)
+                       g_signal_stop_emission_by_name (widget, "drag-drop");
+
+               composer->priv->dnd_is_uri = FALSE;
+
                gdk_drag_status (context, GDK_ACTION_COPY, time);
                composer->priv->drop_occured = TRUE;
                gtk_drag_get_data (widget, context, target, time);
@@ -1838,6 +1821,11 @@ msg_composer_drag_data_received_after_cb (GtkWidget *widget,
        WebKitDOMDOMWindow *dom_window;
        WebKitDOMDOMSelection *dom_selection;
 
+       if (!composer->priv->drop_occured)
+               return;
+
+       composer->priv->drop_occured = FALSE;
+
        editor = e_msg_composer_get_editor (composer);
        view = e_html_editor_get_view (editor);
 
@@ -1845,23 +1833,40 @@ msg_composer_drag_data_received_after_cb (GtkWidget *widget,
        dom_window = webkit_dom_document_get_default_view (document);
        dom_selection = webkit_dom_dom_window_get_selection (dom_window);
 
-       /* FIXME When the user drops something inside the view and it is
-        * added as an EAttachment, WebKit still inserts the URI of the
-        * resource into the view. Let's delete it as it is selected. */
-       if (composer->priv->remove_inserted_uri_on_drop)
-               webkit_dom_dom_selection_delete_from_document (dom_selection);
-       else {
-               /* When text is DnD'ed into the view, WebKit will select it. So let's
-                * collapse it to its end to have the caret after the DnD'ed text. */
-               webkit_dom_dom_selection_collapse_to_end (dom_selection, NULL);
-       }
-
+       /* When text is DnD'ed into the view, WebKit will select it. So let's
+        * collapse it to its end to have the caret after the DnD'ed text. */
        webkit_dom_dom_selection_collapse_to_end (dom_selection, NULL);
+
        e_html_editor_view_check_magic_links (view, FALSE);
        /* Also force spell check on view. */
        e_html_editor_view_force_spell_check (view);
 }
 
+static gchar *
+next_uri (guchar **uri_list,
+          gint *len,
+          gint *list_len)
+{
+       guchar *uri, *begin;
+
+       begin = *uri_list;
+       *len = 0;
+       while (**uri_list && **uri_list != '\n' && **uri_list != '\r' && *list_len) {
+               (*uri_list) ++;
+               (*len) ++;
+               (*list_len) --;
+       }
+
+       uri = (guchar *) g_strndup ((gchar *) begin, *len);
+
+       while ((!**uri_list || **uri_list == '\n' || **uri_list == '\r') && *list_len) {
+               (*uri_list) ++;
+               (*list_len) --;
+       }
+
+       return (gchar *) uri;
+}
+
 static void
 msg_composer_drag_data_received_cb (GtkWidget *widget,
                                     GdkDragContext *context,
@@ -1875,7 +1880,7 @@ msg_composer_drag_data_received_cb (GtkWidget *widget,
        EHTMLEditor *editor;
        EHTMLEditorView *html_editor_view;
        EHTMLEditorSelection *editor_selection;
-       gboolean html_mode;
+       gboolean html_mode, same_widget = FALSE;
        GtkWidget *source_widget;
 
        editor = e_msg_composer_get_editor (composer);
@@ -1883,12 +1888,6 @@ msg_composer_drag_data_received_cb (GtkWidget *widget,
        html_mode = e_html_editor_view_get_html_mode (html_editor_view);
        editor_selection = e_html_editor_view_get_selection (html_editor_view);
 
-       if (!composer->priv->drop_occured)
-               return;
-
-       composer->priv->remove_inserted_uri_on_drop = FALSE;
-       composer->priv->drop_occured = FALSE;
-
        /* When we are doind DnD just inside the web view, the DnD is supposed
         * to move things around. */
        source_widget = gtk_drag_get_source_widget (context);
@@ -1897,13 +1896,38 @@ msg_composer_drag_data_received_cb (GtkWidget *widget,
                EHTMLEditorView *editor_view = e_html_editor_get_view (editor);
 
                if ((gpointer) editor_view == (gpointer) source_widget)
-                       return;
+                       same_widget = TRUE;
+       }
+
+       /* Leave DnD inside the view on WebKit. */
+       if (composer->priv->drop_occured && same_widget) {
+               gdk_drag_status (context, 0, time);
+               return;
+       }
+
+       if (!composer->priv->drop_occured) {
+               if (!same_widget) {
+                       /* Check if we are DnD'ing some URI, if so WebKit will
+                        * insert the URI into the view and we have to prevent it
+                        * from doing that. */
+                       if (info == DND_TARGET_TYPE_TEXT_URI_LIST) {
+                               gchar **uris;
+
+                               uris = gtk_selection_data_get_uris (selection);
+                               composer->priv->dnd_is_uri = uris != NULL;
+                               g_strfreev (uris);
+                       }
+               }
+               return;
        }
 
+       composer->priv->dnd_is_uri = FALSE;
+
        /* Leave the text on WebKit to handle it. */
        if (info == DND_TARGET_TYPE_UTF8_STRING ||
            info == DND_TARGET_TYPE_STRING ||
-           info == DND_TARGET_TYPE_TEXT_PLAIN) {
+           info == DND_TARGET_TYPE_TEXT_PLAIN ||
+           info == DND_TARGET_TYPE_TEXT_PLAIN_UTF8) {
                gdk_drag_status (context, 0, time);
                return;
        }
@@ -1922,6 +1946,8 @@ msg_composer_drag_data_received_cb (GtkWidget *widget,
                        return;
                }
 
+               e_html_editor_selection_set_on_point (editor_selection, x, y);
+
                list_len = length;
                do {
                        text = next_uri ((guchar **) &data, &len, &list_len);
@@ -1955,6 +1981,8 @@ msg_composer_drag_data_received_cb (GtkWidget *widget,
                        return;
                }
 
+               e_html_editor_selection_set_on_point (editor_selection, x, y);
+
                list_len = length;
                do {
                        uri = next_uri ((guchar **) &data, &len, &list_len);
@@ -1976,6 +2004,8 @@ msg_composer_drag_data_received_cb (GtkWidget *widget,
                        return;
                }
 
+               e_html_editor_selection_set_on_point (editor_selection, x, y);
+
                list_len = length;
                do {
                        uri = next_uri ((guchar **) &data, &len, &list_len);
@@ -1987,12 +2017,6 @@ msg_composer_drag_data_received_cb (GtkWidget *widget,
        } else {
                EAttachmentView *view = e_msg_composer_get_attachment_view (composer);
 
-               /* FIXME When the user drops something inside the view and it is
-                * added as an EAttachment, WebKit still inserts the URI of the
-                * resource into the view. Now we are deleting it in
-                * msg_composer_drag_data_received_after_cb, but there has to be
-                * a way how to tell the WebKit to not process this drop. */
-               composer->priv->remove_inserted_uri_on_drop = TRUE;
                /* Forward the data to the attachment view.  Note that calling
                 * e_attachment_view_drag_data_received() will not work because
                 * that function only handles the case where all the other drag


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