[polari/wip/fmuellner/drop-target: 7/12] entryArea: Support pasting text/image content from files
- From: Florian Müllner <fmuellner src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [polari/wip/fmuellner/drop-target: 7/12] entryArea: Support pasting text/image content from files
- Date: Sat, 7 May 2016 20:05:59 +0000 (UTC)
commit e69402d961d6b60d673159c4b294f0f0b93f7456
Author: Florian Müllner <fmuellner gnome org>
Date: Fri Feb 12 05:30:45 2016 +0100
entryArea: Support pasting text/image content from files
For users, it is not immediately obvious why they can copy file contents
in a text/image editor and paste it into Polari for uploading, but trying
to paste the file itself only inserts a (most likely useless) URI.
Instead, accept file pastes and upload the contents to the appropriate
service if possible.
https://bugzilla.gnome.org/show_bug.cgi?id=766066
src/entryArea.js | 64 ++++++++++++++++++++++++++++++++++++++------------
src/pasteManager.js | 40 +++++++++++++++++++++++++++++++
2 files changed, 88 insertions(+), 16 deletions(-)
---
diff --git a/src/entryArea.js b/src/entryArea.js
index 3fc9810..dd2d853 100644
--- a/src/entryArea.js
+++ b/src/entryArea.js
@@ -23,7 +23,8 @@ const ChatEntry = new Lang.Class({
Extends: Gtk.Entry,
Signals: { 'text-pasted': { param_types: [GObject.TYPE_STRING,
GObject.TYPE_INT] },
- 'image-pasted': { param_types: [GdkPixbuf.Pixbuf.$gtype] } },
+ 'image-pasted': { param_types: [GdkPixbuf.Pixbuf.$gtype] },
+ 'file-pasted': { param_types: [Gio.File.$gtype] } },
_init: function(params) {
this.parent(params);
@@ -38,21 +39,12 @@ const ChatEntry = new Lang.Class({
}
let clipboard = Gtk.Clipboard.get_default(this.get_display());
- clipboard.request_text(Lang.bind(this,
- function(clipboard, text) {
- if (text == null)
- return;
- text = text.trim();
-
- let nLines = text.split('\n').length;
- if (nLines >= MAX_LINES) {
- this.emit('text-pasted', text, nLines);
- return;
- }
-
- this._useDefaultHandler = true;
- this.emit('paste-clipboard');
- this._useDefaultHandler = false;
+ clipboard.request_uris(Lang.bind(this,
+ function(clipboard, uris) {
+ if (uris && uris.length)
+ this.emit('file-pasted', Gio.File.new_for_uri(uris[0]));
+ else
+ clipboard.request_text(Lang.bind(this, this._onTextReceived));
}));
clipboard.request_image(Lang.bind(this,
@@ -62,6 +54,22 @@ const ChatEntry = new Lang.Class({
this.emit('image-pasted', pixbuf);
}));
},
+
+ _onTextReceived: function(clipboard, text) {
+ if (text == null)
+ return;
+ text = text.trim();
+
+ let nLines = text.split('\n').length;
+ if (nLines >= MAX_LINES) {
+ this.emit('text-pasted', text, nLines);
+ return;
+ }
+
+ this._useDefaultHandler = true;
+ this.emit('paste-clipboard');
+ this._useDefaultHandler = false;
+ }
});
const EntryArea = new Lang.Class({
@@ -118,6 +126,7 @@ const EntryArea = new Lang.Class({
this._chatEntry.connect('text-pasted', Lang.bind(this, this._onTextPasted));
this._chatEntry.connect('image-pasted', Lang.bind(this, this._onImagePasted));
+ this._chatEntry.connect('file-pasted', Lang.bind(this, this._onFilePasted));
this._chatEntry.connect('changed', Lang.bind(this, this._onEntryChanged));
this._chatEntry.connect('activate', Lang.bind(this,
@@ -249,6 +258,29 @@ const EntryArea = new Lang.Class({
this._setPasteContent(pixbuf);
},
+ _onFilePasted: function(entry, file) {
+ file.query_info_async(Gio.FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
+ Gio.FileQueryInfoFlags.NONE,
+ GLib.PRIORITY_DEFAULT, null,
+ Lang.bind(this, this._onFileInfoReady));
+ },
+
+ _onFileInfoReady: function(file, res) {
+ let fileInfo = null;
+ try {
+ fileInfo = file.query_info_finish(res);
+ } catch(e) {
+ return;
+ }
+
+ let name = fileInfo.get_display_name();
+ /* Translators: %s is a filename */
+ this._confirmLabel.label = _("Upload “%s” to public paste service?").format(name);
+ /* Translators: %s is a filename */
+ this._uploadLabel.label = _("Uploading “%s” to public paste service …").format(name);
+ this._setPasteContent(file);
+ },
+
_onPasteClicked: function() {
let title;
let nick = this._room.channel.connection.self_contact.alias;
diff --git a/src/pasteManager.js b/src/pasteManager.js
index 848d0a7..2c11301 100644
--- a/src/pasteManager.js
+++ b/src/pasteManager.js
@@ -73,11 +73,51 @@ const PasteManager = new Lang.Class({
Utils.gpaste(content, title, callback);
} else if (content instanceof GdkPixbuf.Pixbuf) {
Utils.imgurPaste(content, title, callback);
+ } else if (content.query_info_async) {
+ this._pasteFile(content, title, callback);
} else {
throw new Error('Unhandled content type');
}
},
+ _pasteFile: function(file, title, callback) {
+ file.query_info_async(Gio.FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
+ Gio.FileQueryInfoFlags.NONE,
+ GLib.PRIORITY_DEFAULT, null,
+ Lang.bind(this, this._onFileQueryFinish, title, callback));
+ },
+
+ _onFileQueryFinish: function(file, res, title, callback) {
+ let fileInfo = null;
+ try {
+ fileInfo = file.query_info_finish(res);
+ } catch(e) {
+ callback(null);
+ }
+
+ let contentType = fileInfo.get_content_type();
+ let targetType = this._getTargetForContentType(contentType);
+
+ if (targetType == DndTargetType.TEXT)
+ file.load_contents_async(null, Lang.bind(this,
+ function(f, res) {
+ let [, contents, ,] = f.load_contents_finish(res);
+ Utils.gpaste(contents.toString(), title, callback);
+ }));
+ else if (targetType == DndTargetType.IMAGE)
+ file.read_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this,
+ function(f, res) {
+ let stream = f.read_finish(res);
+ GdkPixbuf.Pixbuf.new_from_stream_async(stream, null,
+ Lang.bind(this, function(stream, res) {
+ let pixbuf = GdkPixbuf.Pixbuf.new_from_stream_finish(res);
+ Utils.imgurPaste(pixbuf, title, callback);
+ }));
+ }));
+ else
+ callback(null);
+ },
+
_onDragDrop: function(widget, context, x, y, time) {
if (!Polari.drag_dest_supports_target(widget, context, null))
return Gdk.EVENT_PROPAGATE;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]