From 1267c4d659996b2cd9a4a52f5ba6a79c5b623e03 Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Sat, 3 Aug 2013 18:08:09 -0400 Subject: [PATCH] Closes #77, Create linked files with drag and drop The cursor effect doesn't work reliably anywhere other than on Linux, but external files can now be linked instead of stored with Cmd-Option-drag on OS X and Ctrl-Shift-drag on Win/Linux. --- .../zotero/xpcom/collectionTreeView.js | 41 ++++++++++++++++--- chrome/content/zotero/xpcom/itemTreeView.js | 41 +++++++++++++++++-- chrome/content/zotero/xpcom/zotero.js | 12 +++--- 3 files changed, 80 insertions(+), 14 deletions(-) diff --git a/chrome/content/zotero/xpcom/collectionTreeView.js b/chrome/content/zotero/xpcom/collectionTreeView.js index 17af51602..23864d2e0 100644 --- a/chrome/content/zotero/xpcom/collectionTreeView.js +++ b/chrome/content/zotero/xpcom/collectionTreeView.js @@ -1725,7 +1725,16 @@ Zotero.CollectionTreeView.prototype.drop = function(row, orient) try { Zotero.DB.beginTransaction(); - var itemID = Zotero.Attachments.importFromFile(file, false, targetLibraryID); + if (dragData.dropEffect == 'link') { + var itemID = Zotero.Attachments.linkFromFile(file); + } + else { + if (dragData.dropEffect != 'copy') { + Components.utils.reportError("Invalid dropEffect '" + dragData.dropEffect + "' dropping file"); + } + var itemID = Zotero.Attachments.importFromFile(file, false, targetLibraryID); + } + if (parentCollectionID) { var col = Zotero.Collections.get(parentCollectionID); if (col) { @@ -1751,17 +1760,38 @@ Zotero.CollectionTreeView.prototype.drop = function(row, orient) * Called by HTML 5 Drag and Drop when dragging over the tree */ Zotero.CollectionTreeView.prototype.onDragEnter = function (event) { - //Zotero.debug("Storing current drag data"); Zotero.DragDrop.currentDataTransfer = event.dataTransfer; + return false; } /* * Called by HTML 5 Drag and Drop when dragging over the tree */ -Zotero.CollectionTreeView.prototype.onDragOver = function (event, dropdata, session) { +Zotero.CollectionTreeView.prototype.onDragOver = function (event) { + Zotero.DragDrop.currentDataTransfer = event.dataTransfer; + if (event.dataTransfer.types.contains("application/x-moz-file")) { + // As of Aug. 2013 nightlies: + // + // - Setting the dropEffect only works on Linux and OS X. + // + // - Modifier keys don't show up in the drag event on OS X until the + // drop, so since we can't show a correct effect, we leave it at + // the default 'move', the least misleading option. + // + // - The cursor effect gets set by the system on Windows 7 and can't + // be overridden. + if (!Zotero.isMac) { + if (event.ctrlKey && event.shiftKey) { + event.dataTransfer.dropEffect = "link"; + } + else { + event.dataTransfer.dropEffect = "copy"; + } + } + } // Show copy symbol when dragging an item over a collection - if (event.dataTransfer.getData("zotero/item")) { + else if (event.dataTransfer.getData("zotero/item")) { event.dataTransfer.dropEffect = "copy"; } return false; @@ -1771,7 +1801,8 @@ Zotero.CollectionTreeView.prototype.onDragOver = function (event, dropdata, sess /* * Called by HTML 5 Drag and Drop when dropping onto the tree */ -Zotero.CollectionTreeView.prototype.onDrop = function (event, dropdata, session) { +Zotero.CollectionTreeView.prototype.onDrop = function (event) { + Zotero.DragDrop.currentDataTransfer = event.dataTransfer; return false; } diff --git a/chrome/content/zotero/xpcom/itemTreeView.js b/chrome/content/zotero/xpcom/itemTreeView.js index 04ff52950..fde9c11b3 100644 --- a/chrome/content/zotero/xpcom/itemTreeView.js +++ b/chrome/content/zotero/xpcom/itemTreeView.js @@ -2990,7 +2990,15 @@ Zotero.ItemTreeView.prototype.drop = function(row, orient) try { Zotero.DB.beginTransaction(); - var itemID = Zotero.Attachments.importFromFile(file, sourceItemID, targetLibraryID); + if (dragData.dropEffect == 'link') { + var itemID = Zotero.Attachments.linkFromFile(file, sourceItemID); + } + else { + if (dragData.dropEffect != 'copy') { + Components.utils.reportError("Invalid dropEffect '" + dragData.dropEffect + "' dropping file"); + } + var itemID = Zotero.Attachments.importFromFile(file, sourceItemID, targetLibraryID); + } if (parentCollectionID) { var col = Zotero.Collections.get(parentCollectionID); if (col) { @@ -3012,21 +3020,46 @@ Zotero.ItemTreeView.prototype.drop = function(row, orient) } Zotero.ItemTreeView.prototype.onDragEnter = function (event) { - //Zotero.debug("Storing current drag data"); Zotero.DragDrop.currentDataTransfer = event.dataTransfer; + return false; } /* * Called by HTML 5 Drag and Drop when dragging over the tree */ -Zotero.ItemTreeView.prototype.onDragOver = function (event, dropdata, session) { +Zotero.ItemTreeView.prototype.onDragOver = function (event) { + Zotero.DragDrop.currentDataTransfer = event.dataTransfer; + if (event.dataTransfer.types.contains("application/x-moz-file")) { + // As of Aug. 2013 nightlies: + // + // - Setting the dropEffect only works on Linux and OS X. + // + // - Modifier keys don't show up in the drag event on OS X until the + // drop, so since we can't show a correct effect, we leave it at + // the default 'move', the least misleading option. + // + // - The cursor effect gets set by the system on Windows 7 and can't + // be overridden. + if (!Zotero.isMac) { + if (event.ctrlKey && event.shiftKey) { + event.dataTransfer.dropEffect = "link"; + } + else { + event.dataTransfer.dropEffect = "copy"; + } + } + } + // Show copy symbol when dragging an item over a collection + else if (event.dataTransfer.getData("zotero/item")) { + event.dataTransfer.dropEffect = "copy"; + } return false; } /* * Called by HTML 5 Drag and Drop when dropping onto the tree */ -Zotero.ItemTreeView.prototype.onDrop = function (event, dropdata, session) { +Zotero.ItemTreeView.prototype.onDrop = function (event) { return false; } diff --git a/chrome/content/zotero/xpcom/zotero.js b/chrome/content/zotero/xpcom/zotero.js index f2587e938..450e1c13e 100644 --- a/chrome/content/zotero/xpcom/zotero.js +++ b/chrome/content/zotero/xpcom/zotero.js @@ -2381,17 +2381,19 @@ Zotero.DragDrop = { currentDataTransfer: null, getDragData: function (element, firstOnly) { - var dragData = { - dataType: '', - data: [] - }; - var dt = this.currentDataTransfer; if (!dt) { Zotero.debug("Drag data not available"); return false; } + var dragData = { + dataType: '', + data: [], + dropEffect: dt.dropEffect + }; + + var len = firstOnly ? 1 : dt.mozItemCount; if (dt.types.contains('zotero/collection')) {