From a5a27a740077b6d962f3377979ca4e922bd8ffcd Mon Sep 17 00:00:00 2001 From: David Norton Date: Mon, 26 Jun 2006 17:51:18 +0000 Subject: [PATCH] Fixes #27, collapsable/hierarchical notes in center pane. - This required moving the icon to the title field so that the indent would work out right. The type column (which for new installs will be hidden) displays the type in text. - I expect several small bugs in regard to this. --- .../content/scholar/itemTreeView.js | 239 +++++++++++++++--- chrome/chromeFiles/content/scholar/overlay.js | 3 +- .../chromeFiles/content/scholar/overlay.xul | 12 +- .../skin/default/scholar/overlay.css | 5 + 4 files changed, 222 insertions(+), 37 deletions(-) diff --git a/chrome/chromeFiles/content/scholar/itemTreeView.js b/chrome/chromeFiles/content/scholar/itemTreeView.js index 91fba9221..7c9790837 100644 --- a/chrome/chromeFiles/content/scholar/itemTreeView.js +++ b/chrome/chromeFiles/content/scholar/itemTreeView.js @@ -14,7 +14,8 @@ Scholar.ItemTreeView = function(itemGroup) this._itemGroup = itemGroup; this._treebox = null; - this._savedSelection = null; + this._savedSelectionItems = null; + this._savedSelectionNotes = null; this.refresh(); this._unregisterID = Scholar.Notifier.registerItemTree(this); @@ -51,7 +52,7 @@ Scholar.ItemTreeView.prototype.refresh = function() var newRows = this._itemGroup.getChildItems(); for(var i = 0; i < newRows.length; i++) if(newRows[i]) - this._showItem(newRows[i], i+1); //item ref, before row + this._showItem(new Scholar.ItemTreeView.TreeRow('item',newRows[i],null,0,false), i+1); //item ref, before row this._refreshHashMap(); } @@ -94,9 +95,18 @@ Scholar.ItemTreeView.prototype.notify = function(action, type, ids) } else if(action == 'modify') //must check for null because it could legitimately be 0 { - if(this._itemRowMap[ids] != null) + var row = this._itemRowMap[ids]; + if( row != null) { - this._treebox.invalidateRow(row); + if(this.isContainer(row) && this.isContainerOpen(row)) + { + this.toggleOpenState(row); + this.toggleOpenState(row); + } + else + { + this._treebox.invalidateRow(row); + } madeChanges = true; } } @@ -164,7 +174,11 @@ Scholar.ItemTreeView.prototype.getCellText = function(row, column) if(c) //don't display '0' val = c; } - else if(column.id != "typeIcon") + else if(column.id == "typeIcon") + { + val = Scholar.getString('itemTypes.'+Scholar.ItemTypes.getName(obj.getType())); + } + else { val = obj.getField(column.id); } @@ -179,13 +193,93 @@ Scholar.ItemTreeView.prototype.getCellText = function(row, column) Scholar.ItemTreeView.prototype.getImageSrc = function(row, col) { - if(col.id == 'typeIcon') + if(col.id == 'title') { - var itemType = Scholar.ItemTypes.getName(this._getItemAtRow(row).getType()); + var itemType; + if(this._getItemAtRow(row).isNote()) + itemType = 'note'; + else + itemType = Scholar.ItemTypes.getName(this._getItemAtRow(row).getType()); + return "chrome://scholar/skin/treeitem-"+itemType+".png"; } } +Scholar.ItemTreeView.prototype.isContainer = function(row) +{ + return !this._getItemAtRow(row).isNote(); +} + +Scholar.ItemTreeView.prototype.isContainerOpen = function(row) +{ + return this._dataItems[row].isOpen; +} + +Scholar.ItemTreeView.prototype.isContainerEmpty = function(row) +{ + return (this._getItemAtRow(row).numNotes() == 0); +} + +Scholar.ItemTreeView.prototype.getLevel = function(row) +{ + return this._getItemAtRow(row).level; +} + +Scholar.ItemTreeView.prototype.getParentIndex = function(row) +{ + var thisLevel = this.getLevel(row); + if(thisLevel == 0) return -1; + for(var i = row - 1; i >= 0; i--) + if(this.getLevel(i) < thisLevel) + return i; + return -1; +} + +Scholar.ItemTreeView.prototype.hasNextSibling = function(row,afterIndex) +{ + var thisLevel = this.getLevel(row); + for(var i = afterIndex + 1; i < this.rowCount; i++) + { + var nextLevel = this.getLevel(i); + if(nextLevel == thisLevel) return true; + else if(nextLevel < thisLevel) return false; + } +} + +Scholar.ItemTreeView.prototype.toggleOpenState = function(row) +{ + var count = 0; //used to tell the tree how many rows were added/removed + var thisLevel = this.getLevel(row); + + if(this.isContainerOpen(row)) + { + while((row + 1 < this._dataItems.length) && (this.getLevel(row + 1) > thisLevel)) + { + this._hideItem(row+1); + count--; //count is negative when closing a container because we are removing rows + } + } + else + { + var item = this._getItemAtRow(row).ref; + var newRows = item.getNotes(); //Get children + + for(var i = 0; i < newRows.length; i++) + { + count++; + this._showItem(new Scholar.ItemTreeView.TreeRow('note',item,newRows[i],thisLevel+1,false), row+i+1); //item ref, before row + } + } + + this._treebox.beginUpdateBatch(); + + this._dataItems[row].isOpen = !this._dataItems[row].isOpen; + this._treebox.rowCountChanged(row+1, count); //tell treebox to repaint these + this._treebox.invalidateRow(row); + this._treebox.endUpdateBatch(); + this._refreshHashMap(); +} + Scholar.ItemTreeView.prototype.isSorted = function() { for(var i=0, len=this._treebox.columns.count; i b.getField('dateModified')) ? -1 : (a.getField('dateModified') < b.getField('dateModified')) ? 1 : 0; } + var openRows = new Array(); + for(var i = 0; i < this._dataItems.length; i++) + { + if(this.isContainer(i) && this.isContainerOpen(i)) + { + openRows.push(this._getItemAtRow(i).ref.getID()); + this.toggleOpenState(i); + } + } + if(order) this._dataItems.sort(oppositeSort); else @@ -288,6 +392,9 @@ Scholar.ItemTreeView.prototype.sort = function() this._refreshHashMap(); + for(var i = 0; i < openRows.length; i++) + this.toggleOpenState(this._itemRowMap[openRows[i]]); + } //////////////////////////////////////////////////////////////////////////////// @@ -303,7 +410,13 @@ Scholar.ItemTreeView.prototype.deleteSelection = function() { if(this.selection.count == 0) return; - + + //collapse open items + for(var i=0; i - - @@ -116,6 +111,11 @@ label="&items.numNotes_column;" persist="width ordinal hidden sortActive sortDirection"/> +