From 442d20b387b4315f3e45a8d8c23b43c686c1dd47 Mon Sep 17 00:00:00 2001 From: abakkk Date: Wed, 9 Sep 2020 22:25:56 +0200 Subject: [PATCH] paste image files from clipboard --- area.js | 11 ++- extension.js | 1 + files.js | 82 +++++++++++++----- schemas/gschemas.compiled | Bin 7137 -> 7216 bytes ...extensions.draw-on-your-screen.gschema.xml | 4 + 5 files changed, 74 insertions(+), 24 deletions(-) diff --git a/area.js b/area.js index 321fb84..fedd40f 100644 --- a/area.js +++ b/area.js @@ -190,7 +190,7 @@ var DrawingArea = new Lang.Class({ }, getImages() { - let images = Files.getImages(); + let images = Files.Images.getImages(); if (!images[this.currentImage]) this.currentImage = Math.max(images.length - 1, 0); return images; @@ -998,6 +998,15 @@ var DrawingArea = new Lang.Class({ this.emit('show-osd-gicon', images[this.currentImage].gicon, images[this.currentImage].toString(), "", -1, false); }, + pasteImageFiles: function() { + Files.Images.addImagesFromClipboard((images, index) => { + this.currentImage = index; + this.currentTool = Shapes.IMAGE; + this.updatePointerCursor(); + this.emit('show-osd-gicon', images[this.currentImage].gicon, images[this.currentImage].toString(), "", -1, false); + }); + }, + toggleHelp: function() { if (this.helper.visible) { this.helper.hideHelp(); diff --git a/extension.js b/extension.js index 4395725..d838cf9 100644 --- a/extension.js +++ b/extension.js @@ -180,6 +180,7 @@ const AreaManager = new Lang.Class({ 'decrement-line-width': () => this.activeArea.incrementLineWidth(-1), 'increment-line-width-more': () => this.activeArea.incrementLineWidth(5), 'decrement-line-width-more': () => this.activeArea.incrementLineWidth(-5), + 'paste-image-files': this.activeArea.pasteImageFiles.bind(this.activeArea), 'switch-linejoin': this.activeArea.switchLineJoin.bind(this.activeArea), 'switch-linecap': this.activeArea.switchLineCap.bind(this.activeArea), 'switch-fill-rule': this.activeArea.switchFillRule.bind(this.activeArea), diff --git a/files.js b/files.js index 484a78c..b345c16 100644 --- a/files.js +++ b/files.js @@ -1,5 +1,5 @@ /* jslint esversion: 6 */ -/* exported Image, getImages, Json, getJsons, getDateString */ +/* exported Image, Images, Json, getJsons, getDateString */ /* * Copyright 2019 Abakkk @@ -27,11 +27,14 @@ const GdkPixbuf = imports.gi.GdkPixbuf; const Gio = imports.gi.Gio; const GLib = imports.gi.GLib; const Lang = imports.lang; +const St = imports.gi.St; const ExtensionUtils = imports.misc.extensionUtils; const Me = ExtensionUtils.getCurrentExtension(); const EXAMPLE_IMAGES = Me.dir.get_child('data').get_child('images'); const USER_IMAGES = Gio.File.new_for_path(GLib.build_filenamev([GLib.get_user_data_dir(), Me.metadata['data-dir'], 'images'])); +const Clipboard = St.Clipboard.get_default(); +const CLIPBOARD_TYPE = St.ClipboardType.CLIPBOARD; // wrapper around an image file var Image = new Lang.Class({ @@ -125,31 +128,64 @@ var Image = new Lang.Class({ } }); -var getImages = function() { - let images = []; +var Images = { + clipboardImages: [], - [EXAMPLE_IMAGES, USER_IMAGES].forEach(directory => { - let enumerator; - try { - enumerator = directory.enumerate_children('standard::display-name,standard::content-type', Gio.FileQueryInfoFlags.NONE, null); - } catch(e) { - return; - } + getImages: function() { + let images = []; - let fileInfo = enumerator.next_file(null); - while (fileInfo) { - if (fileInfo.get_content_type().indexOf('image') == 0) - images.push(new Image({ file: enumerator.get_child(fileInfo), contentType: fileInfo.get_content_type(), displayName: fileInfo.get_display_name() })); - fileInfo = enumerator.next_file(null); - } - enumerator.close(null); - }); + [EXAMPLE_IMAGES, USER_IMAGES].forEach(directory => { + let enumerator; + try { + enumerator = directory.enumerate_children('standard::display-name,standard::content-type', Gio.FileQueryInfoFlags.NONE, null); + } catch(e) { + return; + } + + let fileInfo = enumerator.next_file(null); + while (fileInfo) { + if (fileInfo.get_content_type().indexOf('image') == 0) + images.push(new Image({ file: enumerator.get_child(fileInfo), contentType: fileInfo.get_content_type(), displayName: fileInfo.get_display_name() })); + fileInfo = enumerator.next_file(null); + } + enumerator.close(null); + }); + + images.sort((a, b) => { + return a.displayName.localeCompare(b.displayName); + }); + + return images.concat(this.clipboardImages); + }, - images.sort((a, b) => { - return a.displayName.localeCompare(b.displayName); - }); - - return images; + addImagesFromClipboard: function(callback) { + Clipboard.get_text(CLIPBOARD_TYPE, (clipBoard, text) => { + if (!text) + return; + + let lines = text.split('\n'); + if (lines[0] == 'x-special/nautilus-clipboard') + lines = lines.slice(2); + + let images = lines.filter(line => !!line) + .map(line => Gio.File.new_for_commandline_arg(line)) + .filter(file => file.query_exists(null)) + .map(file => [file, file.query_info('standard::display-name,standard::content-type', Gio.FileQueryInfoFlags.NONE, null)]) + .filter(pair => pair[1].get_content_type().indexOf('image') == 0) + .map(pair => new Image({ file: pair[0], contentType: pair[1].get_content_type(), displayName: pair[1].get_display_name() })); + + // Prevent duplicated + images.filter(image => !this.clipboardImages.map(clipboardImage => clipboardImage.file).some(clipboardFile => clipboardFile.equal(image.file))) + .forEach(image => this.clipboardImages.push(image)); + + if (images.length) { + let lastFile = images[images.length - 1].file; + let allImages = this.getImages(); + let index = allImages.findIndex(image => image.file.equal(lastFile)); + callback(allImages, index); + } + }); + } }; // wrapper around a json file diff --git a/schemas/gschemas.compiled b/schemas/gschemas.compiled index 411939e81af313d67a206371573b8906ca47bd6a..0dcf5fba49ed9dbd8e6ce1ab30bc9e3d255b7906 100644 GIT binary patch delta 2600 zcmZveZA?>F0EQ1LtXdT42Q6*c3Nl39#qyybb`-91rFe4fJGncuHz3*+QU?h2X-@fOb zbI->;_nv!eMjHD+%o)3Ma<4VDTBQHxLl%H%X0Z_7`V)Rf$DH1dd>lFnKL7rtn>ju2Yf0JBTX6B!)9mT*nYTg1!1G3V zl-JX^J_MZr?+>pSV@~f!Zozt$fYgCUbv_pGhYbY*=w|Td8s%%| z^iJe$&@k{l^u?Le=Oa%-`#@dal55QA+0GF361X4n++j}7{3i5g(7k@oMdT^-2d8=p zVGf>}o5qRDtU%8SZfF2(D*EeB=JcHEP0&_Q@bG8_b9!DMf*uAx{kH1}b9&B1KXe$} z`DI`pb9#?R^@tlVW8m=Ut_c>V35IsB82yFuO z5A4It>6y1fli=g4ts~6o`Ox)4&w^YGgzeJ{@rpPHO=3^Jb$wJ%nHBJZPh&rH82sCO zHNc#{0Qm@X6y(-?wum`>G4e6!@4!~vJ|=WF;}Pg>aAvTwir3R~029z6ylJ*%uBYeqe&{B! zwfU5}jp^B;77zA+2MaP4=vg5N9R!6BR0ez96>wuAlQ~^h@K4{gARf1nVg>a2=q4Ck;&l$!b9Eq-I)CeiMnlKbhVwV;%gnZyB!448RU>V2- zc>qtpd6>Za0NW=0-R8l9gL@wEyS)Ou09JuoPzUNk1K?j7;2~ok;5Q#HG4s$+1LXmP z=K*{&#BO}k%>x7v0@(lNVSqES2=Ii0x2fQpPXW&Yd;vu{s0KVRECk#wJn7^E3y^Nl za+!mtQ1iNKvy&FjtZ@u;peflI(h{hFzwC8A@_tE!9P}1iA7?>%!M;1EM!se%ccf=H z$gQWuR9!O+O~}cjx;!(gmA$s5*7P;|)I>3z=sxmt&3<(qpU3X^^Y!ugfZX{`@t#&9uGs Ef5}x4Z~y=R delta 2566 zcmZveeQXnD0LHJ#WHPpO?fP9{D`SkoVaGNZhOYtgF_CN_$wE}9-EA$jy>h+509`R5 z5h57iHIWzy1EX1p$wr6-%?R+{P)TO+4~TyN5zRs%8U7&}4D)%ex2_{L`R#e`c|Y&H zd+%L;!~I3aj#vgR9Nkt>STBwLEJB{_OXnka1xy8npcq&|39y@#LLI;b+`tQ_gPEZ0 z1!m!Tj0*VKIaI<|fw`bMLwd|eGJ*v!P=jkyYf=ZDckuM;0CWH|ERc3fgU~zR%*o0s z=Jch=N1z^?B(+vu{fs$1^B}Yltn7L`6p+%Hi$WAMBTRx-MnT3iKY*+UtTuCc=Kati zQ2ca%1qYzFAs>eR1Ku#})3bg)ma_`1F?0IDGzuDETESYgfSwH^&_iJ7vsym~pyvQR z&T~U z@YaCJ+~UOZ=SyToSPoW{{Plzd^c)}vZ3MS|Ju!(ny%+g*XcrjNKe@=9o-20@+6%Vq zdQ{1r-huoY^fst_WIxNC-dLeDOg{G2>AuX2=s6)bv>MbNF1o@7^c-LXv;}lG`5!Q+ z=gLK(=fRBVlo;GL5IOeZ)}t~ zJ(u)v=n9V{UHh=Rfc?p0XG5V)x|CgaRfOUQTGt^HT z7re832%mrxqxZjMNAz3?er?>~y{p$_%;}AN3~dC~d)jm6^mf#5g(~2kMe_H|>G=o_ zK#zmfO{a{Pl)gYpW2P{dK+pC|?QB5LI~auC0iO@F^fRaD03*;mpCtYA`{sSj>A6B~ z=v)wM*|wZHJ-6jLr~>k8zMjgQ-iiDG^!S_j;|?xe#e(DTT!~)jccAs;r7xM&b3#MV z`yjO^s)r+Tdo&i4mNaY8cu3p3EF=|(A3c6C>B1$Z2%q2VGni_n|a@IK0Fck?U6;{mFi(>J7V!CaO_}OF6mo;U#qNNnE z(YZKnoVEq1JP+XOZXAx-*?6C@(*RFid~}Ty_9f_KkO!uKv6Frp{Mbp)Q<$fC9jFCC zz(aTvm=6|$mjO@iS9w@kV9EhcYyNn|7Xj=ELU+O=(lJcWo~2zKM&=cU;ywV~SBvd}UuXWkE8eM zCfZaClFj#xy>;g9Q4_knM~QYsbkxeJw?|C%)C-(T;)bn4G?u!`CKPv0?4~W0iii!^ zPO@vdEv~A1M2>}0x{PfUR}#87;__6QJ1DN=CDv6nmOEP9>@J!RVNWoxv8_#Vi2=92 jVZxx=*r1u+8INk3s*UxPGxsn)0`J;["<Primary><Shift>o"] Open previous drawing + + ["<Primary>v"] + Paste image files from the clipboard + ["<Primary><Shift>z"] Redo last brushstroke