Allow items to be moved (not copied) between collections w/modifier key
Cmd on OS X, Shift on Windows/Linux How do I not get to close a ticket for this? Unfortunately on Windows it doesn't seem possible to set the cursor effect to arbitrary states (see note in libraryTreeView.js:: _setDropEffect() for the gory details), so this just uses the default cursor there. On OS X and Linux the cursor reflects the requested action.
This commit is contained in:
parent
ea97c3d956
commit
d318bca7a4
6 changed files with 379 additions and 208 deletions
|
@ -48,6 +48,16 @@ Zotero.CollectionTreeView = function()
|
|||
this._trashNotEmpty = {};
|
||||
}
|
||||
|
||||
Zotero.CollectionTreeView.prototype = Object.create(Zotero.LibraryTreeView.prototype);
|
||||
Zotero.CollectionTreeView.prototype.type = 'collection';
|
||||
|
||||
Object.defineProperty(Zotero.CollectionTreeView.prototype, "itemGroup", {
|
||||
get: function () {
|
||||
return this.getItemGroupAtRow(this.selection.currentIndex);
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
/*
|
||||
* Called by the tree itself
|
||||
*/
|
||||
|
@ -980,8 +990,10 @@ Zotero.CollectionTreeView.prototype._hideItem = function(row)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* Returns Zotero.ItemGroup at row
|
||||
*
|
||||
* @deprecated Use getItemGroupAtRow()
|
||||
*/
|
||||
Zotero.CollectionTreeView.prototype._getItemAtRow = function(row)
|
||||
{
|
||||
|
@ -989,6 +1001,12 @@ Zotero.CollectionTreeView.prototype._getItemAtRow = function(row)
|
|||
}
|
||||
|
||||
|
||||
Zotero.CollectionTreeView.prototype.getItemGroupAtRow = function(row)
|
||||
{
|
||||
return this._dataItems[row][0];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Saves the ids of the currently selected item for later
|
||||
*/
|
||||
|
@ -1155,7 +1173,7 @@ Zotero.CollectionTreeCommandController.prototype.onEvent = function(evt)
|
|||
* Start a drag using HTML 5 Drag and Drop
|
||||
*/
|
||||
Zotero.CollectionTreeView.prototype.onDragStart = function(event) {
|
||||
var itemGroup = this._getItemAtRow(this.selection.currentIndex);
|
||||
var itemGroup = this.itemGroup;
|
||||
if (!itemGroup.isCollection()) {
|
||||
return;
|
||||
}
|
||||
|
@ -1163,18 +1181,16 @@ Zotero.CollectionTreeView.prototype.onDragStart = function(event) {
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* Called while a drag is over the tree.
|
||||
/**
|
||||
* Called by treechildren.onDragOver() before setting the dropEffect,
|
||||
* which is checked in libraryTreeView.canDrop()
|
||||
*/
|
||||
Zotero.CollectionTreeView.prototype.canDrop = function(row, orient, dragData)
|
||||
{
|
||||
Zotero.CollectionTreeView.prototype.canDropCheck = function (row, orient, dataTransfer) {
|
||||
//Zotero.debug("Row is " + row + "; orient is " + orient);
|
||||
|
||||
if (!dragData || !dragData.data) {
|
||||
var dragData = Zotero.DragDrop.getDragData(this);
|
||||
}
|
||||
|
||||
var dragData = Zotero.DragDrop.getDataFromDataTransfer(dataTransfer);
|
||||
if (!dragData) {
|
||||
Zotero.debug("No drag data");
|
||||
return false;
|
||||
}
|
||||
var dataType = dragData.dataType;
|
||||
|
@ -1184,8 +1200,8 @@ Zotero.CollectionTreeView.prototype.canDrop = function(row, orient, dragData)
|
|||
if (orient == 1 && row == 0 && dataType == 'zotero/collection') {
|
||||
return true;
|
||||
}
|
||||
else if(orient == 0) //directly on a row...
|
||||
{
|
||||
// Directly on a row
|
||||
else if (orient == 0) {
|
||||
var itemGroup = this._getItemAtRow(row); //the collection we are dragging over
|
||||
|
||||
if (dataType == 'zotero/item' && itemGroup.isBucket()) {
|
||||
|
@ -1331,17 +1347,21 @@ Zotero.CollectionTreeView.prototype.canDrop = function(row, orient, dragData)
|
|||
/*
|
||||
* Called when something's been dropped on or next to a row
|
||||
*/
|
||||
Zotero.CollectionTreeView.prototype.drop = function(row, orient)
|
||||
Zotero.CollectionTreeView.prototype.drop = function(row, orient, dataTransfer)
|
||||
{
|
||||
var dragData = Zotero.DragDrop.getDragData(this);
|
||||
|
||||
if (!this.canDrop(row, orient, dragData)) {
|
||||
if (!this.canDropCheck(row, orient, dataTransfer)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var dragData = Zotero.DragDrop.getDataFromDataTransfer(dataTransfer);
|
||||
if (!dragData) {
|
||||
Zotero.debug("No drag data");
|
||||
return false;
|
||||
}
|
||||
var dropEffect = dragData.dropEffect;
|
||||
var dataType = dragData.dataType;
|
||||
var data = dragData.data;
|
||||
var itemGroup = this._getItemAtRow(row);
|
||||
var itemGroup = this.getItemGroupAtRow(row);
|
||||
|
||||
function copyItem (item, targetLibraryID) {
|
||||
// Check if there's already a copy of this item in the library
|
||||
|
@ -1589,6 +1609,7 @@ Zotero.CollectionTreeView.prototype.drop = function(row, orient)
|
|||
|
||||
var newItems = [];
|
||||
var newIDs = [];
|
||||
var toMove = [];
|
||||
// TODO: support items coming from different sources?
|
||||
if (items[0].libraryID == targetLibraryID) {
|
||||
var sameLibrary = true;
|
||||
|
@ -1604,6 +1625,7 @@ Zotero.CollectionTreeView.prototype.drop = function(row, orient)
|
|||
|
||||
if (sameLibrary) {
|
||||
newIDs.push(item.id);
|
||||
toMove.push(item.id);
|
||||
}
|
||||
else {
|
||||
newItems.push(item);
|
||||
|
@ -1667,6 +1689,18 @@ Zotero.CollectionTreeView.prototype.drop = function(row, orient)
|
|||
collection.addItems(newIDs);
|
||||
}
|
||||
|
||||
// If moving, remove items from source collection
|
||||
if (dropEffect == 'move' && toMove.length) {
|
||||
if (!sameLibrary) {
|
||||
throw new Error("Cannot move items between libraries");
|
||||
}
|
||||
let itemGroup = Zotero.DragDrop.getDragSource();
|
||||
if (!itemGroup || !itemGroup.isCollection()) {
|
||||
throw new Error("Drag source must be a collection for move action");
|
||||
}
|
||||
itemGroup.ref.removeItems(toMove);
|
||||
}
|
||||
|
||||
Zotero.DB.commitTransaction();
|
||||
}
|
||||
else if (dataType == 'text/x-moz-url' || dataType == 'application/x-moz-file') {
|
||||
|
@ -1725,7 +1759,7 @@ Zotero.CollectionTreeView.prototype.drop = function(row, orient)
|
|||
|
||||
try {
|
||||
Zotero.DB.beginTransaction();
|
||||
if (dragData.dropEffect == 'link') {
|
||||
if (dropEffect == 'link') {
|
||||
var itemID = Zotero.Attachments.linkFromFile(file);
|
||||
}
|
||||
else {
|
||||
|
@ -1740,7 +1774,6 @@ Zotero.CollectionTreeView.prototype.drop = function(row, orient)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (parentCollectionID) {
|
||||
var col = Zotero.Collections.get(parentCollectionID);
|
||||
if (col) {
|
||||
|
@ -1762,85 +1795,6 @@ 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.DragDrop.currentDataTransfer = event.dataTransfer;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Called by HTML 5 Drag and Drop when dragging over the tree
|
||||
*/
|
||||
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 (https://bugzilla.mozilla.org/show_bug.cgi?id=911918),
|
||||
// so since we can't show a correct effect, we leave it at
|
||||
// the default 'move', the least misleading option, and set it
|
||||
// below in onDrop().
|
||||
//
|
||||
// - The cursor effect gets set by the system on Windows 7 and can't
|
||||
// be overridden.
|
||||
if (!Zotero.isMac) {
|
||||
if (event.shiftKey) {
|
||||
if (event.ctrlKey) {
|
||||
event.dataTransfer.dropEffect = "link";
|
||||
}
|
||||
else {
|
||||
event.dataTransfer.dropEffect = "move";
|
||||
}
|
||||
}
|
||||
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.CollectionTreeView.prototype.onDrop = function (event) {
|
||||
if (event.dataTransfer.types.contains("application/x-moz-file")) {
|
||||
if (Zotero.isMac) {
|
||||
Zotero.DragDrop.currentDataTransfer = event.dataTransfer;
|
||||
if (event.metaKey) {
|
||||
if (event.altKey) {
|
||||
event.dataTransfer.dropEffect = 'link';
|
||||
}
|
||||
else {
|
||||
event.dataTransfer.dropEffect = 'move';
|
||||
}
|
||||
}
|
||||
else {
|
||||
event.dataTransfer.dropEffect = 'copy';
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Zotero.CollectionTreeView.prototype.onDragExit = function (event) {
|
||||
//Zotero.debug("Clearing drag data");
|
||||
Zotero.DragDrop.currentDataTransfer = null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
|
|
|
@ -38,11 +38,14 @@ Zotero.ItemTreeView = function(itemGroup, sourcesOnly)
|
|||
{
|
||||
this.wrappedJSObject = this;
|
||||
this.rowCount = 0;
|
||||
this.itemGroup = itemGroup;
|
||||
// Deprecated
|
||||
// TODO: remove
|
||||
this._itemGroup = itemGroup;
|
||||
|
||||
this._initialized = false;
|
||||
this._skipKeypress = false;
|
||||
|
||||
this._itemGroup = itemGroup;
|
||||
this._sourcesOnly = sourcesOnly;
|
||||
|
||||
this._callbacks = [];
|
||||
|
@ -59,6 +62,8 @@ Zotero.ItemTreeView = function(itemGroup, sourcesOnly)
|
|||
);
|
||||
}
|
||||
|
||||
Zotero.ItemTreeView.prototype = Object.create(Zotero.LibraryTreeView.prototype);
|
||||
Zotero.ItemTreeView.prototype.type = 'item';
|
||||
|
||||
Zotero.ItemTreeView.prototype.addCallback = function(callback) {
|
||||
this._callbacks.push(callback);
|
||||
|
@ -2427,6 +2432,11 @@ Zotero.ItemTreeCommandController.prototype.onEvent = function(evt)
|
|||
* Start a drag using HTML 5 Drag and Drop
|
||||
*/
|
||||
Zotero.ItemTreeView.prototype.onDragStart = function (event) {
|
||||
// See note in LibraryTreeView::_setDropEffect()
|
||||
if (Zotero.isWin) {
|
||||
event.dataTransfer.effectAllowed = 'move';
|
||||
}
|
||||
|
||||
var itemIDs = this.saveSelection();
|
||||
var items = Zotero.Items.get(itemIDs);
|
||||
|
||||
|
@ -2741,17 +2751,14 @@ Zotero.ItemTreeView.fileDragDataProvider.prototype = {
|
|||
}
|
||||
|
||||
|
||||
Zotero.ItemTreeView.prototype.canDrop = function(row, orient, dragData)
|
||||
{
|
||||
Zotero.debug("Row is " + row + "; orient is " + orient);
|
||||
/**
|
||||
* Called by treechildren.onDragOver() before setting the dropEffect,
|
||||
* which is checked in libraryTreeView.canDrop()
|
||||
*/
|
||||
Zotero.ItemTreeView.prototype.canDropCheck = function (row, orient, dataTransfer) {
|
||||
//Zotero.debug("Row is " + row + "; orient is " + orient);
|
||||
|
||||
if (row == -1 && orient == -1) {
|
||||
//return true;
|
||||
}
|
||||
|
||||
if (!dragData || !dragData.data) {
|
||||
var dragData = Zotero.DragDrop.getDragData(this);
|
||||
}
|
||||
var dragData = Zotero.DragDrop.getDataFromDataTransfer(dataTransfer);
|
||||
if (!dragData) {
|
||||
Zotero.debug("No drag data");
|
||||
return false;
|
||||
|
@ -2869,18 +2876,21 @@ Zotero.ItemTreeView.prototype.canDrop = function(row, orient, dragData)
|
|||
/*
|
||||
* Called when something's been dropped on or next to a row
|
||||
*/
|
||||
Zotero.ItemTreeView.prototype.drop = function(row, orient)
|
||||
{
|
||||
var dragData = Zotero.DragDrop.getDragData(this);
|
||||
|
||||
if (!this.canDrop(row, orient, dragData)) {
|
||||
Zotero.ItemTreeView.prototype.drop = function(row, orient, dataTransfer) {
|
||||
if (!this.canDropCheck(row, orient, dataTransfer)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var dragData = Zotero.DragDrop.getDataFromDataTransfer(dataTransfer);
|
||||
if (!dragData) {
|
||||
Zotero.debug("No drag data");
|
||||
return false;
|
||||
}
|
||||
var dropEffect = dragData.dropEffect;
|
||||
var dataType = dragData.dataType;
|
||||
var data = dragData.data;
|
||||
|
||||
var itemGroup = this._itemGroup;
|
||||
var itemGroup = this.itemGroup;
|
||||
var targetLibraryID = itemGroup.isWithinGroup() ? itemGroup.ref.libraryID : null;
|
||||
|
||||
if (dataType == 'zotero/item') {
|
||||
var ids = data;
|
||||
|
@ -2889,6 +2899,19 @@ Zotero.ItemTreeView.prototype.drop = function(row, orient)
|
|||
return;
|
||||
}
|
||||
|
||||
// TEMP: This is always false for now, since cross-library drag
|
||||
// is disallowed in canDropCheck()
|
||||
//
|
||||
// TODO: support items coming from different sources?
|
||||
if (items[0].libraryID == targetLibraryID) {
|
||||
var sameLibrary = true;
|
||||
}
|
||||
else {
|
||||
var sameLibrary = false;
|
||||
}
|
||||
|
||||
var toMove = [];
|
||||
|
||||
// Dropped directly on a row
|
||||
if (orient == 0) {
|
||||
// Set drop target as the parent item for dragged items
|
||||
|
@ -2926,9 +2949,24 @@ Zotero.ItemTreeView.prototype.drop = function(row, orient)
|
|||
item.save()
|
||||
}
|
||||
itemGroup.ref.addItem(item.id);
|
||||
toMove.push(item.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If moving, remove items from source collection
|
||||
if (dropEffect == 'move' && toMove.length) {
|
||||
if (!sameLibrary) {
|
||||
throw new Error("Cannot move items between libraries");
|
||||
}
|
||||
let targetItemGroup = Zotero.DragDrop.getDragSource();
|
||||
if (!targetItemGroup || !targetItemGroup.isCollection()) {
|
||||
throw new Error("Drag source must be a collection");
|
||||
}
|
||||
if (itemGroup.id != targetItemGroup.id) {
|
||||
itemGroup.ref.removeItems(toMove);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (dataType == 'text/x-moz-url' || dataType == 'application/x-moz-file') {
|
||||
// Disallow drop into read-only libraries
|
||||
|
@ -3011,7 +3049,7 @@ Zotero.ItemTreeView.prototype.drop = function(row, orient)
|
|||
|
||||
try {
|
||||
Zotero.DB.beginTransaction();
|
||||
if (dragData.dropEffect == 'link') {
|
||||
if (dropEffect == 'link') {
|
||||
var itemID = Zotero.Attachments.linkFromFile(file, sourceItemID);
|
||||
}
|
||||
else {
|
||||
|
@ -3046,79 +3084,6 @@ Zotero.ItemTreeView.prototype.drop = function(row, orient)
|
|||
}
|
||||
}
|
||||
|
||||
Zotero.ItemTreeView.prototype.onDragEnter = function (event) {
|
||||
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) {
|
||||
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 (https://bugzilla.mozilla.org/show_bug.cgi?id=911918),
|
||||
// so since we can't show a correct effect, we leave it at
|
||||
// the default 'move', the least misleading option, and set it
|
||||
// below in onDrop().
|
||||
//
|
||||
// - The cursor effect gets set by the system on Windows 7 and can't
|
||||
// be overridden.
|
||||
if (!Zotero.isMac) {
|
||||
if (event.shiftKey) {
|
||||
if (event.ctrlKey) {
|
||||
event.dataTransfer.dropEffect = "link";
|
||||
}
|
||||
else {
|
||||
event.dataTransfer.dropEffect = "move";
|
||||
}
|
||||
}
|
||||
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) {
|
||||
if (event.dataTransfer.types.contains("application/x-moz-file")) {
|
||||
if (Zotero.isMac) {
|
||||
Zotero.DragDrop.currentDataTransfer = event.dataTransfer;
|
||||
if (event.metaKey) {
|
||||
if (event.altKey) {
|
||||
event.dataTransfer.dropEffect = 'link';
|
||||
}
|
||||
else {
|
||||
event.dataTransfer.dropEffect = 'move';
|
||||
}
|
||||
}
|
||||
else {
|
||||
event.dataTransfer.dropEffect = 'copy';
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Zotero.ItemTreeView.prototype.onDragExit = function (event) {
|
||||
//Zotero.debug("Clearing drag data");
|
||||
Zotero.DragDrop.currentDataTransfer = null;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
|
|
216
chrome/content/zotero/xpcom/libraryTreeView.js
Normal file
216
chrome/content/zotero/xpcom/libraryTreeView.js
Normal file
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
***** BEGIN LICENSE BLOCK *****
|
||||
|
||||
Copyright © 2013 Center for History and New Media
|
||||
George Mason University, Fairfax, Virginia, USA
|
||||
http://zotero.org
|
||||
|
||||
This file is part of Zotero.
|
||||
|
||||
Zotero is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Zotero is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with Zotero. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
***** END LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
Zotero.LibraryTreeView = function () {};
|
||||
Zotero.LibraryTreeView.prototype = {
|
||||
/**
|
||||
* Called while a drag is over the tree
|
||||
*/
|
||||
canDrop: function(row, orient, dataTransfer) {
|
||||
// onDragOver() calls the view's canDropCheck() and sets the
|
||||
// dropEffect, which we check here. Setting the dropEffect on the
|
||||
// dataTransfer here seems to have no effect.
|
||||
|
||||
// ondragover doesn't have access to the orientation on its own,
|
||||
// so we stuff it in Zotero.DragDrop
|
||||
Zotero.DragDrop.currentOrientation = orient;
|
||||
|
||||
return dataTransfer.dropEffect && dataTransfer.dropEffect != "none";
|
||||
},
|
||||
|
||||
|
||||
/*
|
||||
* Called by HTML 5 Drag and Drop when dragging over the tree
|
||||
*/
|
||||
onDragEnter: function (event) {
|
||||
Zotero.DragDrop.currentDragEvent = event;
|
||||
return false;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Called by HTML 5 Drag and Drop when dragging over the tree
|
||||
*
|
||||
* We use this to set the drag action, which is used by view.canDrop(),
|
||||
* based on the view's canDropCheck() and modifier keys.
|
||||
*/
|
||||
onDragOver: function (event) {
|
||||
// Prevent modifier keys from doing their normal things
|
||||
event.preventDefault();
|
||||
|
||||
Zotero.DragDrop.currentDragEvent = event;
|
||||
|
||||
var target = event.target;
|
||||
if (target.tagName != 'treechildren') {
|
||||
return false;
|
||||
}
|
||||
var tree = target.parentNode;
|
||||
let row = {}, col = {}, obj = {};
|
||||
tree.treeBoxObject.getCellAt(event.clientX, event.clientY, row, col, obj);
|
||||
if (tree.id == 'zotero-collections-tree') {
|
||||
var view = tree.ownerDocument.defaultView.ZoteroPane.collectionsView;
|
||||
}
|
||||
else if (tree.id == 'zotero-items-tree') {
|
||||
var view = tree.ownerDocument.defaultView.ZoteroPane.itemsView;
|
||||
}
|
||||
else {
|
||||
throw new Error("Invalid tree id '" + tree.id + "'");
|
||||
}
|
||||
if (!view.canDropCheck(row.value, Zotero.DragDrop.currentOrientation, event.dataTransfer)) {
|
||||
this._setDropEffect(event, "none");
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.dataTransfer.getData("zotero/item")) {
|
||||
var sourceItemGroup = Zotero.DragDrop.getDragSource();
|
||||
if (sourceItemGroup) {
|
||||
if (this.type == 'collection') {
|
||||
var targetItemGroup = Zotero.DragDrop.getDragTarget();
|
||||
}
|
||||
else if (this.type == 'item') {
|
||||
var targetItemGroup = this.itemGroup;
|
||||
}
|
||||
else {
|
||||
throw new Error("Invalid type '" + this.type + "'");
|
||||
}
|
||||
|
||||
if (!targetItemGroup) {
|
||||
this._setDropEffect(event, "none");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sourceItemGroup.id == targetItemGroup.id) {
|
||||
// Ignore drag into the same collection
|
||||
if (this.type == 'collection') {
|
||||
this._setDropEffect(event, "none");
|
||||
}
|
||||
// If dragging from the same source, do a move
|
||||
else {
|
||||
this._setDropEffect(event, "move");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// If the source isn't a collection, the action has to be a copy
|
||||
if (!sourceItemGroup.isCollection()) {
|
||||
this._setDropEffect(event, "copy");
|
||||
return false;
|
||||
}
|
||||
// For now, all cross-library drags are copies
|
||||
if (sourceItemGroup.ref.libraryID != targetItemGroup.ref.libraryID) {
|
||||
this._setDropEffect(event, "copy");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ((Zotero.isMac && event.metaKey) || (!Zotero.isMac && event.shiftKey)) {
|
||||
this._setDropEffect(event, "move");
|
||||
}
|
||||
else {
|
||||
this._setDropEffect(event, "copy");
|
||||
}
|
||||
}
|
||||
else 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 (https://bugzilla.mozilla.org/show_bug.cgi?id=911918),
|
||||
// so since we can't show a correct effect, we leave it at
|
||||
// the default 'move', the least misleading option, and set it
|
||||
// below in onDrop().
|
||||
//
|
||||
// - The cursor effect gets set by the system on Windows 7 and can't
|
||||
// be overridden.
|
||||
if (!Zotero.isMac) {
|
||||
if (event.shiftKey) {
|
||||
if (event.ctrlKey) {
|
||||
event.dataTransfer.dropEffect = "link";
|
||||
}
|
||||
else {
|
||||
event.dataTransfer.dropEffect = "move";
|
||||
}
|
||||
}
|
||||
else {
|
||||
event.dataTransfer.dropEffect = "copy";
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
|
||||
/*
|
||||
* Called by HTML 5 Drag and Drop when dropping onto the tree
|
||||
*/
|
||||
onDrop: function (event) {
|
||||
// See note above
|
||||
if (event.dataTransfer.types.contains("application/x-moz-file")) {
|
||||
if (Zotero.isMac) {
|
||||
Zotero.DragDrop.currentDragEvent = event;
|
||||
if (event.metaKey) {
|
||||
if (event.altKey) {
|
||||
event.dataTransfer.dropEffect = 'link';
|
||||
}
|
||||
else {
|
||||
event.dataTransfer.dropEffect = 'move';
|
||||
}
|
||||
}
|
||||
else {
|
||||
event.dataTransfer.dropEffect = 'copy';
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
|
||||
onDragExit: function (event) {
|
||||
//Zotero.debug("Clearing drag data");
|
||||
Zotero.DragDrop.currentDragEvent = null;
|
||||
},
|
||||
|
||||
|
||||
_setDropEffect: function (event, effect) {
|
||||
// On Windows (in Fx26), Firefox uses 'move' for unmodified drags,
|
||||
// and 'copy'/'link' for drags with system-default modifier keys,
|
||||
// as long as the actions are allowed by the initial effectAllowed set
|
||||
// in onDragStart, regardless of the effectAllowed or dropEffect set
|
||||
// in onDragOver. To prevent inaccurate 'copy'/'link' cursors, we set
|
||||
// effectAllowed to 'move' in onDragStart, which locks the cursor at
|
||||
// 'move'. ('none' still changes the cursor, but 'copy'/'link' do not.)
|
||||
//
|
||||
// However, since effectAllowed is enforced, leaving it at 'move'
|
||||
// would prevent our default 'copy' from working, so we also have to
|
||||
// set effectAllowed here (called from onDragOver) to the same action
|
||||
// as the dropEffect. This allows the dropEffect setting (which we use
|
||||
// in the tree's canDrop() and drop() to determine the desired action)
|
||||
// to be changed, even if the cursor doesn't reflect the new setting.
|
||||
if (Zotero.isWin) {
|
||||
event.dataTransfer.effectAllowed = effect;
|
||||
}
|
||||
event.dataTransfer.dropEffect = effect;
|
||||
}
|
||||
};
|
|
@ -2386,14 +2386,12 @@ Zotero.VersionHeader = {
|
|||
}
|
||||
|
||||
Zotero.DragDrop = {
|
||||
currentDataTransfer: null,
|
||||
currentDragEvent: null,
|
||||
currentTarget: null,
|
||||
currentOrientation: 0,
|
||||
|
||||
getDragData: function (element, firstOnly) {
|
||||
var dt = this.currentDataTransfer;
|
||||
if (!dt) {
|
||||
Zotero.debug("Drag data not available");
|
||||
return false;
|
||||
}
|
||||
getDataFromDataTransfer: function (dataTransfer, firstOnly) {
|
||||
var dt = dataTransfer;
|
||||
|
||||
var dragData = {
|
||||
dataType: '',
|
||||
|
@ -2401,7 +2399,6 @@ Zotero.DragDrop = {
|
|||
dropEffect: dt.dropEffect
|
||||
};
|
||||
|
||||
|
||||
var len = firstOnly ? 1 : dt.mozItemCount;
|
||||
|
||||
if (dt.types.contains('zotero/collection')) {
|
||||
|
@ -2439,6 +2436,46 @@ Zotero.DragDrop = {
|
|||
}
|
||||
|
||||
return dragData;
|
||||
},
|
||||
|
||||
|
||||
getDragSource: function () {
|
||||
var dt = this.currentDragEvent.dataTransfer;
|
||||
if (!dt) {
|
||||
Zotero.debug("Drag data not available", 2);
|
||||
return false;
|
||||
}
|
||||
|
||||
// For items, the drag source is the ItemGroup of the parent window
|
||||
// of the source tree
|
||||
if (dt.types.contains("zotero/item")) {
|
||||
var sourceNode = dt.mozSourceNode;
|
||||
if (!sourceNode || sourceNode.tagName != 'treechildren'
|
||||
|| sourceNode.parentElement.id != 'zotero-items-tree') {
|
||||
return false;
|
||||
}
|
||||
var win = sourceNode.ownerDocument.defaultView;
|
||||
return win.ZoteroPane.collectionsView.itemGroup;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
getDragTarget: function () {
|
||||
var event = this.currentDragEvent;
|
||||
var target = event.target;
|
||||
if (target.tagName == 'treechildren') {
|
||||
var tree = target.parentNode;
|
||||
if (tree.id == 'zotero-collections-tree') {
|
||||
let row = {}, col = {}, obj = {};
|
||||
tree.treeBoxObject.getCellAt(event.clientX, event.clientY, row, col, obj);
|
||||
let win = tree.ownerDocument.defaultView;
|
||||
return win.ZoteroPane.collectionsView.getItemGroupAtRow(row.value);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -301,10 +301,6 @@
|
|||
<tree id="zotero-collections-tree" hidecolumnpicker="true" context="zotero-collectionmenu"
|
||||
onmouseover="ZoteroPane_Local.collectionsView.setHighlightedRows();"
|
||||
onselect="ZoteroPane_Local.onCollectionSelected();"
|
||||
ondragstart="if (event.target.localName == 'treechildren') { ZoteroPane_Local.collectionsView.onDragStart(event); }"
|
||||
ondragenter="return ZoteroPane_Local.collectionsView.onDragEnter(event)"
|
||||
ondragover="return ZoteroPane_Local.collectionsView.onDragOver(event)"
|
||||
ondrop="return ZoteroPane_Local.collectionsView.onDrop(event)"
|
||||
seltype="cell" flex="1">
|
||||
<treecols>
|
||||
<treecol
|
||||
|
@ -313,7 +309,10 @@
|
|||
primary="true"
|
||||
hideheader="true"/>
|
||||
</treecols>
|
||||
<treechildren/>
|
||||
<treechildren ondragstart="ZoteroPane_Local.collectionsView.onDragStart(event)"
|
||||
ondragenter="return ZoteroPane_Local.collectionsView.onDragEnter(event)"
|
||||
ondragover="return ZoteroPane_Local.collectionsView.onDragOver(event)"
|
||||
ondrop="return ZoteroPane_Local.collectionsView.onDrop(event)"/>
|
||||
</tree>
|
||||
<splitter id="zotero-tags-splitter" onmouseup="ZoteroPane_Local.updateTagSelectorSize()" collapse="after">
|
||||
<grippy oncommand="ZoteroPane_Local.toggleTagSelector()"/>
|
||||
|
@ -338,10 +337,6 @@
|
|||
onfocus="if (ZoteroPane_Local.itemsView.rowCount && !ZoteroPane_Local.itemsView.selection.count) { ZoteroPane_Local.itemsView.selection.select(0); }"
|
||||
onkeydown="ZoteroPane_Local.handleKeyDown(event, this.id)"
|
||||
onselect="ZoteroPane_Local.itemSelected(event)"
|
||||
ondragstart="if (event.target.localName == 'treechildren') { ZoteroPane_Local.itemsView.onDragStart(event); }"
|
||||
ondragenter="return ZoteroPane_Local.itemsView.onDragEnter(event)"
|
||||
ondragover="return ZoteroPane_Local.itemsView.onDragOver(event)"
|
||||
ondrop="return ZoteroPane_Local.itemsView.onDrop(event)"
|
||||
oncommand="ZoteroPane_Local.serializePersist()"
|
||||
flex="1">
|
||||
<treecols id="zotero-items-columns-header">
|
||||
|
@ -519,7 +514,10 @@
|
|||
src="chrome://zotero/skin/treeitem-note-small.png"
|
||||
zotero-persist="width ordinal hidden sortActive sortDirection"/>
|
||||
</treecols>
|
||||
<treechildren/>
|
||||
<treechildren ondragstart="ZoteroPane_Local.itemsView.onDragStart(event)"
|
||||
ondragenter="return ZoteroPane_Local.itemsView.onDragEnter(event)"
|
||||
ondragover="return ZoteroPane_Local.itemsView.onDragOver(event)"
|
||||
ondrop="return ZoteroPane_Local.itemsView.onDrop(event)"/>
|
||||
</tree>
|
||||
|
||||
<!-- Label for displaying messages when items pane is hidden
|
||||
|
|
|
@ -53,6 +53,7 @@ const xpcomFilesAll = [
|
|||
|
||||
/** XPCOM files to be loaded only for local translation and DB access **/
|
||||
const xpcomFilesLocal = [
|
||||
'libraryTreeView',
|
||||
'collectionTreeView',
|
||||
'annotate',
|
||||
'attachments',
|
||||
|
|
Loading…
Add table
Reference in a new issue