diff --git a/chrome/chromeFiles/content/scholar/xpcom/collectionTreeView.js b/chrome/chromeFiles/content/scholar/xpcom/collectionTreeView.js index d5a4dcac88..131a361d3f 100644 --- a/chrome/chromeFiles/content/scholar/xpcom/collectionTreeView.js +++ b/chrome/chromeFiles/content/scholar/xpcom/collectionTreeView.js @@ -473,10 +473,10 @@ Scholar.CollectionTreeView.prototype.canDrop = function(row, orient) nsDragAndDrop.mDragSession = nsDragAndDrop.mDragService.getCurrentSession(); return false; } + var data = dataSet.first.first; var dataType = data.flavour.contentType; - //Highlight the rows correctly on drag: if(orient == 1 && row == 0 && dataType == 'scholar/collection') //for dropping collections into root level { @@ -487,7 +487,24 @@ Scholar.CollectionTreeView.prototype.canDrop = function(row, orient) var rowCollection = this._getItemAtRow(row).ref; //the collection we are dragging over if(dataType == 'scholar/item' || dataType == "text/x-moz-url") - return true; //items can be dropped on anything + { + var ids = data.data.split(','); + for each(var id in ids) + { + var item = Scholar.Items.get(id); + // Can only drag top-level items into collections + if (item.isRegularItem() || !item.getSource()) + { + // Make sure there's at least one item that's not already + // in this collection + if (!rowCollection.hasItem(id)) + { + return true; + } + } + } + return false; + } else if(dataType='scholar/collection' && data.data != rowCollection.getID() && !Scholar.Collections.get(data.data).hasDescendent('collection',rowCollection.getID()) ) return true; //collections cannot be dropped on themselves, nor in their children } @@ -527,8 +544,15 @@ Scholar.CollectionTreeView.prototype.drop = function(row, orient) { var ids = data.data.split(','); var targetCollection = this._getItemAtRow(row).ref; - for(var i = 0; i= 0; i--) @@ -639,7 +665,7 @@ Scholar.ItemTreeView.prototype._refreshHashMap = function() */ Scholar.ItemTreeView.prototype.saveSelection = function() { - savedSelection = new Array(); + var savedSelection = new Array(); var start = new Object(); var end = new Object(); @@ -713,7 +739,7 @@ Scholar.ItemTreeCommandController.prototype.onEvent = function(evt) Scholar.ItemTreeView.prototype.onDragStart = function (evt,transferData,action) { transferData.data=new TransferData(); - transferData.data.addDataForFlavour("scholar/item",this.saveSelection()); + transferData.data.addDataForFlavour("scholar/item", this.saveSelection()); } /* @@ -727,20 +753,192 @@ Scholar.ItemTreeView.prototype.getSupportedFlavours = function () return flavors; } -/* - * Called by nsDragAndDrop.js for any sort of drop on the tree - */ -Scholar.ItemTreeView.prototype.onDrop = function (evt,data,session) +Scholar.ItemTreeView.prototype.canDrop = function(row, orient) { + try + { + var dataSet = nsTransferable.get(this.getSupportedFlavours(), + nsDragAndDrop.getDragData, true); + } + catch (e) + { + // A work around a limitation in nsDragAndDrop.js -- the mDragSession + // is not set until the drag moves over another control. + // (This will only happen if the first drag is from the item list.) + nsDragAndDrop.mDragSession = nsDragAndDrop.mDragService.getCurrentSession(); + return false; + } + + var data = dataSet.first.first; + var dataType = data.flavour.contentType; + var ids = data.data.split(','); // ids of rows we are dragging in + + if (row==-1 && orient==-1) + { + return true; + } + + // workaround... two different services call canDrop + // (nsDragAndDrop, and the tree) -- this is for the former, + // used when dragging between windows + if (typeof row == 'object') + { + // If drag to different window + if (nsDragAndDrop.mDragSession.sourceNode!=row.target) + { + // Check if at least one item (or parent item for children) doesn't + // already exist in target + for each(var id in ids) + { + var item = Scholar.Items.get(id); + + // Skip non-top-level items + if (!item.isRegularItem() && item.getSource()) + { + continue; + } + // DISABLED: move parent on child drag + //var source = item.isRegularItem() ? false : item.getSource(); + //if (!this._itemGroup.ref.hasItem(source ? source : id)) + if (!this._itemGroup.ref.hasItem(id)) + { + return true; + } + } + } + + return false; + } + + //Scholar.debug('row is ' + row); + //Scholar.debug('orient is ' + orient); + + // Highlight the rows correctly on drag + + var rowItem = this._getItemAtRow(row).ref; //the item we are dragging over + if (dataType == 'scholar/item') + { + // Directly on a row + if (orient == 0) + { + for each(var id in ids) + { + var item = Scholar.Items.get(id); + // Only allow dragging of notes and attachments + // that aren't already children of the item + if (!item.isRegularItem() && item.getSource()!=rowItem.getID()) + { + return true; + } + } + } + + // In library, allow children to be dragged out of parent + else if (this._itemGroup.isLibrary()) + { + for each(var id in ids) + { + // Don't allow drag if any top-level items + var item = Scholar.Items.get(id); + if (item.isRegularItem() || !item.getSource()) + { + return false; + } + } + return true; + } + + return false; + } + /* + else if (dataType == "text/x-moz-url") + { + return true; + } + */ + + return false; +} + +/* + * Called when something's been dropped on or next to a row + */ +Scholar.ItemTreeView.prototype.drop = function(row, orient) +{ + try + { + var dataSet = nsTransferable.get(this.getSupportedFlavours(), + nsDragAndDrop.getDragData, true); + } + catch (e) + { + // A work around a limitation in nsDragAndDrop.js -- the mDragSession + // is not set until the drag moves over another control. + // (This will only happen if the first drag is from the item list.) + nsDragAndDrop.mDragSession = nsDragAndDrop.mDragService.getCurrentSession(); + var dataSet = nsTransferable.get(this.getSupportedFlavours(), + nsDragAndDrop.getDragData, true); + } + + var data = dataSet.first.first; var dataType = data.flavour.contentType; - if(dataType == 'scholar/item') + if (dataType == 'scholar/item' && this.canDrop(row, orient)) { - var ids = data.data.split(','); - for(var i = 0; i