From 7fed86b38954a3808b22b10ebb2517b32abfc501 Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Fri, 29 Sep 2006 20:35:19 +0000 Subject: [PATCH] Closes #295, Dragging an independent file/note over an item should turn the file/note into a child item Overhaul of the item drag and drop functionality, allowing dragging notes and attachments into and out of other items and addressing all the related issues that arise when that's possible. Should also be generally smarter about deciding what can be dragged and dropped where and in what modes. Let me know if something doesn't work as you expect. --- .../scholar/xpcom/collectionTreeView.js | 32 ++- .../content/scholar/xpcom/data_access.js | 22 +- .../content/scholar/xpcom/itemTreeView.js | 245 ++++++++++++++++-- 3 files changed, 271 insertions(+), 28 deletions(-) diff --git a/chrome/chromeFiles/content/scholar/xpcom/collectionTreeView.js b/chrome/chromeFiles/content/scholar/xpcom/collectionTreeView.js index d5a4dcac8..131a361d3 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