[polari/wip/fmuellner/drop-target: 6/6] entryArea: Extend drop target support



commit 6b2032795a2e76def51f206c5c7e9a65c42260c5
Author: Florian Müllner <fmuellner gnome org>
Date:   Fri May 6 14:02:10 2016 +0200

    entryArea: Extend drop target support
    
    GtkEntries are drop targets, but the built-in behavior does not match
    how we handle clipboard pastes:
    
     - only text content is supported
     - drop text is always inserted into the entry,
       independent from the number of lines
    
    Make DND and clipboard handling consistent by only using the built-in
    support for text drops that don't exceed the line limit we apply to
    clipboard pastes, and use our own drop target support otherwise.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=766068

 src/entryArea.js |   35 +++++++++++++++++++++++++++++++++++
 1 files changed, 35 insertions(+), 0 deletions(-)
---
diff --git a/src/entryArea.js b/src/entryArea.js
index 3fd1636..4e0c1f7 100644
--- a/src/entryArea.js
+++ b/src/entryArea.js
@@ -21,6 +21,10 @@ const MAX_LINES = 5;
 const ChatEntry = new Lang.Class({
     Name: 'ChatEntry',
     Extends: Gtk.Entry,
+    Implements: [PasteManager.DropTargetIface],
+    Properties: {
+        'can-drop': GObject.ParamSpec.override('can-drop', PasteManager.DropTargetIface),
+    },
     Signals: { 'text-pasted': { param_types: [GObject.TYPE_STRING,
                                               GObject.TYPE_INT] },
                'image-pasted': { param_types: [GdkPixbuf.Pixbuf.$gtype] },
@@ -29,9 +33,25 @@ const ChatEntry = new Lang.Class({
     _init: function(params) {
         this.parent(params);
 
+        PasteManager.DropTargetIface.addTargets(this, this);
+
         this._useDefaultHandler = false;
     },
 
+    get can_drop() {
+        return true;
+    },
+
+    vfunc_drag_data_received: function(context, x, y, data, info, time) {
+        let str = data.get_text();
+        if (!str || str.split('\n').length >= MAX_LINES)
+            // Disable GtkEntry's built-in drop target support
+            return;
+
+         GObject.signal_stop_emission_by_name(this, 'drag-data-received');
+        this.parent(context, x, y, data, info, time);
+    },
+
     vfunc_paste_clipboard: function(entry) {
         if (!this.editable || this._useDefaultHandler) {
             this.parent();
@@ -128,14 +148,29 @@ const EntryArea = new Lang.Class({
             function(entry, text, nLines) {
                 this.pasteText(text, nLines);
             }));
+        this._chatEntry.connect('text-dropped', Lang.bind(this,
+            function(entry, text) {
+                this.pasteText(text, text.split('\n').length);
+            }));
+
         this._chatEntry.connect('image-pasted', Lang.bind(this,
             function(entry, image) {
                 this.pasteImage(image);
             }));
+        this._chatEntry.connect('image-dropped', Lang.bind(this,
+            function(entry, image) {
+                this.pasteImage(image);
+            }));
+
         this._chatEntry.connect('file-pasted', Lang.bind(this,
             function(entry, file) {
                 this.pasteFile(file);
             }));
+        this._chatEntry.connect('file-dropped', Lang.bind(this,
+            function(entry, file) {
+                this.pasteFile(file);
+            }));
+
         this._chatEntry.connect('changed', Lang.bind(this, this._onEntryChanged));
 
         this._chatEntry.connect('activate', Lang.bind(this,


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