Fix placement of saved searches in collections tree
And unify row add/remove handling between collections tree and items tree
This commit is contained in:
parent
67abbc8c4a
commit
2a69885b11
|
@ -136,7 +136,7 @@ Zotero.CollectionTreeView.prototype.refresh = Zotero.Promise.coroutine(function*
|
||||||
// Record open states before refreshing
|
// Record open states before refreshing
|
||||||
if (this._rows) {
|
if (this._rows) {
|
||||||
for (var i=0, len=this._rows.length; i<len; i++) {
|
for (var i=0, len=this._rows.length; i<len; i++) {
|
||||||
var treeRow = this._rows[i][0]
|
var treeRow = this._rows[i];
|
||||||
if (treeRow.ref && treeRow.ref.id == 'commons-header') {
|
if (treeRow.ref && treeRow.ref.id == 'commons-header') {
|
||||||
var commonsExpand = this.isContainerOpen(i);
|
var commonsExpand = this.isContainerOpen(i);
|
||||||
}
|
}
|
||||||
|
@ -172,43 +172,51 @@ Zotero.CollectionTreeView.prototype.refresh = Zotero.Promise.coroutine(function*
|
||||||
|
|
||||||
var oldCount = this.rowCount || 0;
|
var oldCount = this.rowCount || 0;
|
||||||
var newRows = [];
|
var newRows = [];
|
||||||
|
var added = 0;
|
||||||
var self = this;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Add "My Library"
|
// Add "My Library"
|
||||||
//
|
//
|
||||||
this._addRow(
|
this._addRowToArray(
|
||||||
newRows,
|
newRows,
|
||||||
new Zotero.CollectionTreeRow('library', { libraryID: Zotero.Libraries.userLibraryID })
|
new Zotero.CollectionTreeRow('library', { libraryID: Zotero.Libraries.userLibraryID }),
|
||||||
|
added++
|
||||||
);
|
);
|
||||||
yield this._expandRow(newRows, 0);
|
added += yield this._expandRow(newRows, 0);
|
||||||
|
|
||||||
this._addRow(newRows, new Zotero.CollectionTreeRow('separator', false));
|
this._addRowToArray(newRows, new Zotero.CollectionTreeRow('separator', false), added++);
|
||||||
|
|
||||||
// Add "My Publications"
|
// Add "My Publications"
|
||||||
this._addRow(
|
this._addRowToArray(
|
||||||
newRows,
|
newRows,
|
||||||
new Zotero.CollectionTreeRow('publications', {
|
new Zotero.CollectionTreeRow('publications', {
|
||||||
libraryID: Zotero.Libraries.publicationsLibraryID
|
libraryID: Zotero.Libraries.publicationsLibraryID
|
||||||
})
|
}),
|
||||||
|
added++
|
||||||
);
|
);
|
||||||
|
|
||||||
// Add groups
|
// Add groups
|
||||||
var groups = yield Zotero.Groups.getAll();
|
var groups = yield Zotero.Groups.getAll();
|
||||||
if (groups.length) {
|
if (groups.length) {
|
||||||
this._addRow(newRows, new Zotero.CollectionTreeRow('separator', false));
|
this._addRowToArray(
|
||||||
var row = this._addRow(
|
newRows,
|
||||||
|
new Zotero.CollectionTreeRow('separator', false),
|
||||||
|
added++
|
||||||
|
);
|
||||||
|
this._addRowToArray(
|
||||||
newRows,
|
newRows,
|
||||||
new Zotero.CollectionTreeRow('header', {
|
new Zotero.CollectionTreeRow('header', {
|
||||||
id: "group-libraries-header",
|
id: "group-libraries-header",
|
||||||
label: Zotero.getString('pane.collections.groupLibraries'),
|
label: Zotero.getString('pane.collections.groupLibraries'),
|
||||||
libraryID: -1
|
libraryID: -1
|
||||||
}, 0)
|
}, 0),
|
||||||
|
added++
|
||||||
);
|
);
|
||||||
for (let i = 0, len = groups.length; i < len; i++) {
|
for (let i = 0, len = groups.length; i < len; i++) {
|
||||||
this._rowMap['L' + groups[i].libraryID] = this._addRow(
|
this._addRowToArray(
|
||||||
newRows, new Zotero.CollectionTreeRow('group', groups[i])
|
newRows,
|
||||||
|
new Zotero.CollectionTreeRow('group', groups[i]),
|
||||||
|
added++
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -244,8 +252,8 @@ Zotero.CollectionTreeView.prototype.notify = Zotero.Promise.coroutine(function*
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this._collectionRowMap) {
|
if (!this._rowMap) {
|
||||||
Zotero.debug("Collection row map didn't exist in collectionTreeView.notify()");
|
Zotero.debug("Row map didn't exist in collectionTreeView.notify()");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,9 +334,9 @@ Zotero.CollectionTreeView.prototype.notify = Zotero.Promise.coroutine(function*
|
||||||
for (var i=0; i<ids.length; i++) {
|
for (var i=0; i<ids.length; i++) {
|
||||||
var collection = yield Zotero.Collections.getAsync(ids[i]);
|
var collection = yield Zotero.Collections.getAsync(ids[i]);
|
||||||
var parentID = collection.parentID;
|
var parentID = collection.parentID;
|
||||||
if (parentID && this._collectionRowMap[parentID] &&
|
if (parentID && this._rowMap["C" + parentID] &&
|
||||||
!this.isContainerOpen(this._collectionRowMap[parentID])) {
|
!this.isContainerOpen(this._rowMap["C" + parentID])) {
|
||||||
yield this.toggleOpenState(this._collectionRowMap[parentID]);
|
yield this.toggleOpenState(this._rowMap["C" + parentID]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,14 +400,14 @@ Zotero.CollectionTreeView.prototype._addSortedRow = Zotero.Promise.coroutine(fun
|
||||||
let parentID = collection.parentID;
|
let parentID = collection.parentID;
|
||||||
|
|
||||||
// If parent isn't visible, don't add
|
// If parent isn't visible, don't add
|
||||||
if (parentID && this._collectionRowMap[parentID] === undefined) {
|
if (parentID && this._rowMap["C" + parentID] === undefined) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let libraryID = collection.libraryID;
|
let libraryID = collection.libraryID;
|
||||||
let startRow;
|
let startRow;
|
||||||
if (parentID) {
|
if (parentID) {
|
||||||
startRow = this._collectionRowMap[parentID];
|
startRow = this._rowMap["C" + parentID];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
startRow = this._rowMap['L' + libraryID];
|
startRow = this._rowMap['L' + libraryID];
|
||||||
|
@ -450,9 +458,7 @@ Zotero.CollectionTreeView.prototype._addSortedRow = Zotero.Promise.coroutine(fun
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this._addRow(
|
this._addRow(
|
||||||
this._rows,
|
new Zotero.CollectionTreeRow('collection', collection, level),
|
||||||
new Zotero.CollectionTreeRow('collection', collection),
|
|
||||||
level,
|
|
||||||
beforeRow
|
beforeRow
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -476,37 +482,27 @@ Zotero.CollectionTreeView.prototype._addSortedRow = Zotero.Promise.coroutine(fun
|
||||||
var inSearches = false;
|
var inSearches = false;
|
||||||
for (let i = startRow; i < this.rowCount; i++) {
|
for (let i = startRow; i < this.rowCount; i++) {
|
||||||
let treeRow = this.getRow(i);
|
let treeRow = this.getRow(i);
|
||||||
|
Zotero.debug(treeRow.id);
|
||||||
beforeRow = i;
|
beforeRow = i;
|
||||||
|
|
||||||
// If we've moved on to a different library, stop
|
// If we've reached something other than collections, stop
|
||||||
if (treeRow.ref.libraryID != libraryID) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (treeRow.isSearch()) {
|
if (treeRow.isSearch()) {
|
||||||
inSearches = true;
|
|
||||||
|
|
||||||
// If current search sorts after, stop
|
// If current search sorts after, stop
|
||||||
if (Zotero.localeCompare(treeRow.ref.name, search.name) > 0) {
|
if (Zotero.localeCompare(treeRow.ref.name, search.name) > 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If we've found searches but then see something other than a search, stop
|
// If it's not a search and it's not a collection, stop
|
||||||
else if (inSearches) {
|
else if (!treeRow.isCollection()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this._addRow(
|
this._addRow(
|
||||||
this._rows,
|
new Zotero.CollectionTreeRow('search', search, level),
|
||||||
new Zotero.CollectionTreeRow('search', search),
|
|
||||||
level,
|
|
||||||
beforeRow
|
beforeRow
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
this.rowCount++;
|
|
||||||
this._treebox.rowCountChanged(beforeRow, 1);
|
|
||||||
this._refreshRowMap();
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -525,7 +521,7 @@ Zotero.CollectionTreeView.prototype.setHighlightedRows = Zotero.Promise.coroutin
|
||||||
if (id[0] == 'C') {
|
if (id[0] == 'C') {
|
||||||
id = id.substr(1);
|
id = id.substr(1);
|
||||||
yield this.expandToCollection(id);
|
yield this.expandToCollection(id);
|
||||||
row = this._collectionRowMap[id];
|
row = this._rowMap["C" + id];
|
||||||
}
|
}
|
||||||
if (row) {
|
if (row) {
|
||||||
this._highlightedRows[row] = true;
|
this._highlightedRows[row] = true;
|
||||||
|
@ -621,11 +617,6 @@ Zotero.CollectionTreeView.prototype.isContainer = function(row)
|
||||||
return treeRow.isLibrary(true) || treeRow.isCollection() || treeRow.isPublications() || treeRow.isBucket();
|
return treeRow.isLibrary(true) || treeRow.isCollection() || treeRow.isPublications() || treeRow.isBucket();
|
||||||
}
|
}
|
||||||
|
|
||||||
Zotero.CollectionTreeView.prototype.isContainerOpen = function(row)
|
|
||||||
{
|
|
||||||
return this._rows[row][1];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns true if the collection has no child collections
|
* Returns true if the collection has no child collections
|
||||||
*/
|
*/
|
||||||
|
@ -653,11 +644,6 @@ Zotero.CollectionTreeView.prototype.isContainerEmpty = function(row)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Zotero.CollectionTreeView.prototype.getLevel = function(row)
|
|
||||||
{
|
|
||||||
return this._rows[row][2];
|
|
||||||
}
|
|
||||||
|
|
||||||
Zotero.CollectionTreeView.prototype.getParentIndex = function(row)
|
Zotero.CollectionTreeView.prototype.getParentIndex = function(row)
|
||||||
{
|
{
|
||||||
var thisLevel = this.getLevel(row);
|
var thisLevel = this.getLevel(row);
|
||||||
|
@ -798,7 +784,7 @@ Zotero.CollectionTreeView.prototype.expandToCollection = Zotero.Promise.coroutin
|
||||||
yield this.toggleOpenState(libraryRow);
|
yield this.toggleOpenState(libraryRow);
|
||||||
}
|
}
|
||||||
|
|
||||||
var row = this._collectionRowMap[collectionID];
|
var row = this._rowMap["C" + collectionID];
|
||||||
if (row !== undefined) {
|
if (row !== undefined) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -809,7 +795,7 @@ Zotero.CollectionTreeView.prototype.expandToCollection = Zotero.Promise.coroutin
|
||||||
col = yield Zotero.Collections.getAsync(parentID);
|
col = yield Zotero.Collections.getAsync(parentID);
|
||||||
}
|
}
|
||||||
for each(var id in path) {
|
for each(var id in path) {
|
||||||
row = this._collectionRowMap[id];
|
row = this._rowMap["C" + id];
|
||||||
if (!this.isContainerOpen(row)) {
|
if (!this.isContainerOpen(row)) {
|
||||||
yield this.toggleOpenState(row);
|
yield this.toggleOpenState(row);
|
||||||
}
|
}
|
||||||
|
@ -957,8 +943,8 @@ Zotero.CollectionTreeView.prototype.getLastViewedRow = Zotero.Promise.coroutine(
|
||||||
var select = 0;
|
var select = 0;
|
||||||
if (matches) {
|
if (matches) {
|
||||||
if (matches[1] == 'C') {
|
if (matches[1] == 'C') {
|
||||||
if (this._collectionRowMap[matches[2]]) {
|
if (this._rowMap["C" + matches[2]]) {
|
||||||
select = this._collectionRowMap[matches[2]];
|
select = this._rowMap["C" + matches[2]];
|
||||||
}
|
}
|
||||||
// Search recursively
|
// Search recursively
|
||||||
else {
|
else {
|
||||||
|
@ -986,11 +972,11 @@ Zotero.CollectionTreeView.prototype.getLastViewedRow = Zotero.Promise.coroutine(
|
||||||
lastCol = par;
|
lastCol = par;
|
||||||
path.push(lastCol);
|
path.push(lastCol);
|
||||||
}
|
}
|
||||||
while (!this._collectionRowMap[lastCol] && failsafe > 0)
|
while (!this._rowMap["C" + lastCol] && failsafe > 0)
|
||||||
if (path.length) {
|
if (path.length) {
|
||||||
for (var i=path.length-1; i>=0; i--) {
|
for (var i=path.length-1; i>=0; i--) {
|
||||||
var id = path[i];
|
var id = path[i];
|
||||||
var row = this._collectionRowMap[id];
|
var row = this._rowMap["C" + id];
|
||||||
if (!row) {
|
if (!row) {
|
||||||
var msg = "Collection not found in tree in "
|
var msg = "Collection not found in tree in "
|
||||||
+ "Zotero.CollectionTreeView.setTree()";
|
+ "Zotero.CollectionTreeView.setTree()";
|
||||||
|
@ -1000,8 +986,8 @@ Zotero.CollectionTreeView.prototype.getLastViewedRow = Zotero.Promise.coroutine(
|
||||||
}
|
}
|
||||||
if (!this.isContainerOpen(row)) {
|
if (!this.isContainerOpen(row)) {
|
||||||
yield this.toggleOpenState(row);
|
yield this.toggleOpenState(row);
|
||||||
if (this._collectionRowMap[matches[2]]) {
|
if (this._rowMap["C" + matches[2]]) {
|
||||||
select = this._collectionRowMap[matches[2]];
|
select = this._rowMap["C" + matches[2]];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1081,8 +1067,8 @@ Zotero.CollectionTreeView.prototype.deleteSelection = Zotero.Promise.coroutine(f
|
||||||
* Expand row based on last state, or manually from toggleOpenState()
|
* Expand row based on last state, or manually from toggleOpenState()
|
||||||
*/
|
*/
|
||||||
Zotero.CollectionTreeView.prototype._expandRow = Zotero.Promise.coroutine(function* (rows, row, forceOpen) {
|
Zotero.CollectionTreeView.prototype._expandRow = Zotero.Promise.coroutine(function* (rows, row, forceOpen) {
|
||||||
var treeRow = rows[row][0];
|
var treeRow = rows[row];
|
||||||
var level = rows[row][2];
|
var level = rows[row].level;
|
||||||
var isLibrary = treeRow.isLibrary(true);
|
var isLibrary = treeRow.isLibrary(true);
|
||||||
var isGroup = treeRow.isGroup();
|
var isGroup = treeRow.isGroup();
|
||||||
var isCollection = treeRow.isCollection();
|
var isCollection = treeRow.isCollection();
|
||||||
|
@ -1120,7 +1106,7 @@ Zotero.CollectionTreeView.prototype._expandRow = Zotero.Promise.coroutine(functi
|
||||||
if (!forceOpen &&
|
if (!forceOpen &&
|
||||||
(this._containerState[treeRow.id] === false
|
(this._containerState[treeRow.id] === false
|
||||||
|| (isCollection && !this._containerState[treeRow.id]))) {
|
|| (isCollection && !this._containerState[treeRow.id]))) {
|
||||||
rows[row][1] = false;
|
rows[row].isOpen = false;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1129,7 +1115,7 @@ Zotero.CollectionTreeView.prototype._expandRow = Zotero.Promise.coroutine(functi
|
||||||
// If this isn't a manual open, set the initial state depending on whether
|
// If this isn't a manual open, set the initial state depending on whether
|
||||||
// there are child nodes
|
// there are child nodes
|
||||||
if (!forceOpen) {
|
if (!forceOpen) {
|
||||||
rows[row][1] = startOpen;
|
rows[row].isOpen = startOpen;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!startOpen) {
|
if (!startOpen) {
|
||||||
|
@ -1140,17 +1126,15 @@ Zotero.CollectionTreeView.prototype._expandRow = Zotero.Promise.coroutine(functi
|
||||||
|
|
||||||
// Add collections
|
// Add collections
|
||||||
for (var i = 0, len = collections.length; i < len; i++) {
|
for (var i = 0, len = collections.length; i < len; i++) {
|
||||||
var newRow = this._addRow(
|
let beforeRow = row + 1 + newRows;
|
||||||
|
this._addRowToArray(
|
||||||
rows,
|
rows,
|
||||||
new Zotero.CollectionTreeRow('collection', collections[i]),
|
new Zotero.CollectionTreeRow('collection', collections[i], level + 1),
|
||||||
level + 1,
|
beforeRow
|
||||||
row + 1 + newRows
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Recursively expand child collections that should be open
|
|
||||||
newRows += yield this._expandRow(rows, newRow);
|
|
||||||
|
|
||||||
newRows++;
|
newRows++;
|
||||||
|
// Recursively expand child collections that should be open
|
||||||
|
newRows += yield this._expandRow(rows, beforeRow);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isCollection) {
|
if (isCollection) {
|
||||||
|
@ -1159,14 +1143,22 @@ Zotero.CollectionTreeView.prototype._expandRow = Zotero.Promise.coroutine(functi
|
||||||
|
|
||||||
// Add searches
|
// Add searches
|
||||||
for (var i = 0, len = savedSearches.length; i < len; i++) {
|
for (var i = 0, len = savedSearches.length; i < len; i++) {
|
||||||
this._addRow(rows, new Zotero.CollectionTreeRow('search', savedSearches[i]), level + 1, row + 1 + newRows);
|
this._addRowToArray(
|
||||||
|
rows,
|
||||||
|
new Zotero.CollectionTreeRow('search', savedSearches[i], level + 1),
|
||||||
|
row + 1 + newRows
|
||||||
|
);
|
||||||
newRows++;
|
newRows++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Duplicate items
|
// Duplicate items
|
||||||
if (showDuplicates) {
|
if (showDuplicates) {
|
||||||
let d = new Zotero.Duplicates(libraryID);
|
let d = new Zotero.Duplicates(libraryID);
|
||||||
this._addRow(rows, new Zotero.CollectionTreeRow('duplicates', d), level + 1, row + 1 + newRows);
|
this._addRowToArray(
|
||||||
|
rows,
|
||||||
|
new Zotero.CollectionTreeRow('duplicates', d, level + 1),
|
||||||
|
row + 1 + newRows
|
||||||
|
);
|
||||||
newRows++;
|
newRows++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1177,7 +1169,11 @@ Zotero.CollectionTreeView.prototype._expandRow = Zotero.Promise.coroutine(functi
|
||||||
s.name = Zotero.getString('pane.collections.unfiled');
|
s.name = Zotero.getString('pane.collections.unfiled');
|
||||||
s.addCondition('libraryID', 'is', libraryID);
|
s.addCondition('libraryID', 'is', libraryID);
|
||||||
s.addCondition('unfiled', 'true');
|
s.addCondition('unfiled', 'true');
|
||||||
this._addRow(rows, new Zotero.CollectionTreeRow('unfiled', s), level + 1, row + 1 + newRows);
|
this._addRowToArray(
|
||||||
|
rows,
|
||||||
|
new Zotero.CollectionTreeRow('unfiled', s, level + 1),
|
||||||
|
row + 1 + newRows
|
||||||
|
);
|
||||||
newRows++;
|
newRows++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1187,7 +1183,11 @@ Zotero.CollectionTreeView.prototype._expandRow = Zotero.Promise.coroutine(functi
|
||||||
var ref = {
|
var ref = {
|
||||||
libraryID: libraryID
|
libraryID: libraryID
|
||||||
};
|
};
|
||||||
this._addRow(rows, new Zotero.CollectionTreeRow('trash', ref), level + 1, row + 1 + newRows);
|
this._addRowToArray(
|
||||||
|
rows,
|
||||||
|
new Zotero.CollectionTreeRow('trash', ref, level + 1),
|
||||||
|
row + 1 + newRows
|
||||||
|
);
|
||||||
newRows++;
|
newRows++;
|
||||||
}
|
}
|
||||||
this._trashNotEmpty[libraryID] = !!deletedItems.length;
|
this._trashNotEmpty[libraryID] = !!deletedItems.length;
|
||||||
|
@ -1197,45 +1197,6 @@ Zotero.CollectionTreeView.prototype._expandRow = Zotero.Promise.coroutine(functi
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Called by various view functions to show a row
|
|
||||||
*/
|
|
||||||
Zotero.CollectionTreeView.prototype._addRow = function (rows, treeRow, level, beforeRow) {
|
|
||||||
if (!level) {
|
|
||||||
level = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!beforeRow) {
|
|
||||||
beforeRow = rows.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
rows.splice(beforeRow, 0, [treeRow, false, level]);
|
|
||||||
|
|
||||||
return beforeRow;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Called by view to hide specified row
|
|
||||||
*/
|
|
||||||
Zotero.CollectionTreeView.prototype._removeRow = function(row)
|
|
||||||
{
|
|
||||||
this._rows.splice(row,1);
|
|
||||||
this.rowCount--;
|
|
||||||
if (this.selection.isSelected(row)) {
|
|
||||||
this.selection.toggleSelect(row);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns Zotero.CollectionTreeRow at row
|
|
||||||
*/
|
|
||||||
Zotero.CollectionTreeView.prototype.getRow = function (row) {
|
|
||||||
return this._rows[row][0];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns libraryID or FALSE if not a library
|
* Returns libraryID or FALSE if not a library
|
||||||
*/
|
*/
|
||||||
|
@ -1295,16 +1256,8 @@ Zotero.CollectionTreeView.prototype.rememberSelection = Zotero.Promise.coroutine
|
||||||
*/
|
*/
|
||||||
Zotero.CollectionTreeView.prototype._refreshRowMap = function() {
|
Zotero.CollectionTreeView.prototype._refreshRowMap = function() {
|
||||||
this._rowMap = {};
|
this._rowMap = {};
|
||||||
this._collectionRowMap = {};
|
|
||||||
for (let i = 0, len = this.rowCount; i < len; i++) {
|
for (let i = 0, len = this.rowCount; i < len; i++) {
|
||||||
let treeRow = this.getRow(i);
|
this._rowMap[this.getRow(i).id] = i;
|
||||||
|
|
||||||
this._rowMap[treeRow.id] = i;
|
|
||||||
|
|
||||||
// Collections get special treatment for now
|
|
||||||
if (treeRow.isCollection()) {
|
|
||||||
this._collectionRowMap[treeRow.ref.id] = i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2197,10 +2150,12 @@ Zotero.CollectionTreeCache = {
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
Zotero.CollectionTreeRow = function(type, ref)
|
Zotero.CollectionTreeRow = function(type, ref, level, isOpen)
|
||||||
{
|
{
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.ref = ref;
|
this.ref = ref;
|
||||||
|
this.level = level || 0
|
||||||
|
this.isOpen = isOpen || false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,6 @@ Zotero.ItemTreeView = function (collectionTreeRow, sourcesOnly) {
|
||||||
this._ownerDocument = null;
|
this._ownerDocument = null;
|
||||||
this._needsSort = false;
|
this._needsSort = false;
|
||||||
|
|
||||||
this._rows = [];
|
|
||||||
this._cellTextCache = {};
|
this._cellTextCache = {};
|
||||||
this._itemImages = {};
|
this._itemImages = {};
|
||||||
|
|
||||||
|
@ -355,9 +354,8 @@ Zotero.ItemTreeView.prototype.refresh = Zotero.serial(Zotero.Promise.coroutine(f
|
||||||
this._addRowToArray(
|
this._addRowToArray(
|
||||||
newRows,
|
newRows,
|
||||||
new Zotero.ItemTreeRow(item, 0, false),
|
new Zotero.ItemTreeRow(item, 0, false),
|
||||||
added + 1
|
added++
|
||||||
);
|
);
|
||||||
added++;
|
|
||||||
}
|
}
|
||||||
newSearchItemIDs[item.id] = true;
|
newSearchItemIDs[item.id] = true;
|
||||||
}
|
}
|
||||||
|
@ -369,9 +367,8 @@ Zotero.ItemTreeView.prototype.refresh = Zotero.serial(Zotero.Promise.coroutine(f
|
||||||
this._addRowToArray(
|
this._addRowToArray(
|
||||||
newRows,
|
newRows,
|
||||||
new Zotero.ItemTreeRow(item, 0, false),
|
new Zotero.ItemTreeRow(item, 0, false),
|
||||||
added + 1
|
added++
|
||||||
);
|
);
|
||||||
added++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -414,7 +411,7 @@ Zotero.ItemTreeView.prototype.notify = Zotero.Promise.coroutine(function* (actio
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this._itemRowMap) {
|
if (!this._rowMap) {
|
||||||
Zotero.debug("Item row map didn't exist in itemTreeView.notify()");
|
Zotero.debug("Item row map didn't exist in itemTreeView.notify()");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -449,13 +446,13 @@ Zotero.ItemTreeView.prototype.notify = Zotero.Promise.coroutine(function* (actio
|
||||||
if (extraData.column == 'title') {
|
if (extraData.column == 'title') {
|
||||||
delete this._itemImages[id];
|
delete this._itemImages[id];
|
||||||
}
|
}
|
||||||
this._treebox.invalidateCell(this._itemRowMap[id], col);
|
this._treebox.invalidateCell(this._rowMap[id], col);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for each(var id in ids) {
|
for each(var id in ids) {
|
||||||
delete this._itemImages[id];
|
delete this._itemImages[id];
|
||||||
this._treebox.invalidateRow(this._itemRowMap[id]);
|
this._treebox.invalidateRow(this._rowMap[id]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -485,7 +482,7 @@ Zotero.ItemTreeView.prototype.notify = Zotero.Promise.coroutine(function* (actio
|
||||||
}
|
}
|
||||||
// If refreshing a single item, clear caches and then unselect and reselect row
|
// If refreshing a single item, clear caches and then unselect and reselect row
|
||||||
else if (savedSelection.length == 1 && savedSelection[0] == ids[0]) {
|
else if (savedSelection.length == 1 && savedSelection[0] == ids[0]) {
|
||||||
let row = this._itemRowMap[ids[0]];
|
let row = this._rowMap[ids[0]];
|
||||||
delete this._cellTextCache[row];
|
delete this._cellTextCache[row];
|
||||||
|
|
||||||
this.selection.clearSelection();
|
this.selection.clearSelection();
|
||||||
|
@ -541,7 +538,7 @@ Zotero.ItemTreeView.prototype.notify = Zotero.Promise.coroutine(function* (actio
|
||||||
// On a delete in duplicates mode, just refresh rather than figuring
|
// On a delete in duplicates mode, just refresh rather than figuring
|
||||||
// out what to remove
|
// out what to remove
|
||||||
if (collectionTreeRow.isDuplicates()) {
|
if (collectionTreeRow.isDuplicates()) {
|
||||||
previousRow = this._itemRowMap[ids[0]];
|
previousRow = this._rowMap[ids[0]];
|
||||||
yield this.refresh();
|
yield this.refresh();
|
||||||
madeChanges = true;
|
madeChanges = true;
|
||||||
sort = true;
|
sort = true;
|
||||||
|
@ -561,7 +558,7 @@ Zotero.ItemTreeView.prototype.notify = Zotero.Promise.coroutine(function* (actio
|
||||||
}
|
}
|
||||||
// Row might already be gone (e.g. if this is a child and
|
// Row might already be gone (e.g. if this is a child and
|
||||||
// 'modify' was sent to parent)
|
// 'modify' was sent to parent)
|
||||||
let row = this._itemRowMap[ids[i]];
|
let row = this._rowMap[ids[i]];
|
||||||
if (push && row !== undefined) {
|
if (push && row !== undefined) {
|
||||||
// Don't remove child items from collections, because it's handled by 'modify'
|
// Don't remove child items from collections, because it's handled by 'modify'
|
||||||
if (action == 'remove' && this.getParentIndex(row) != -1) {
|
if (action == 'remove' && this.getParentIndex(row) != -1) {
|
||||||
|
@ -622,7 +619,7 @@ Zotero.ItemTreeView.prototype.notify = Zotero.Promise.coroutine(function* (actio
|
||||||
let item = items[i];
|
let item = items[i];
|
||||||
let id = item.id;
|
let id = item.id;
|
||||||
|
|
||||||
let row = this._itemRowMap[id];
|
let row = this._rowMap[id];
|
||||||
|
|
||||||
// Deleted items get a modify that we have to ignore when
|
// Deleted items get a modify that we have to ignore when
|
||||||
// not viewing the trash
|
// not viewing the trash
|
||||||
|
@ -654,7 +651,7 @@ Zotero.ItemTreeView.prototype.notify = Zotero.Promise.coroutine(function* (actio
|
||||||
}
|
}
|
||||||
// If not moved from under one item to another, just resort the row,
|
// If not moved from under one item to another, just resort the row,
|
||||||
// which also invalidates it and refreshes it
|
// which also invalidates it and refreshes it
|
||||||
else if (!(parentItemID && parentIndex != -1 && this._itemRowMap[parentItemID] != parentIndex)) {
|
else if (!(parentItemID && parentIndex != -1 && this._rowMap[parentItemID] != parentIndex)) {
|
||||||
sort = id;
|
sort = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -734,7 +731,7 @@ Zotero.ItemTreeView.prototype.notify = Zotero.Promise.coroutine(function* (actio
|
||||||
&& collectionTreeRow.ref.libraryID == item.libraryID)
|
&& collectionTreeRow.ref.libraryID == item.libraryID)
|
||||||
|| (collectionTreeRow.isCollection() && item.inCollection(collectionTreeRow.ref.id)))
|
|| (collectionTreeRow.isCollection() && item.inCollection(collectionTreeRow.ref.id)))
|
||||||
// if we haven't already added it to our hash map
|
// if we haven't already added it to our hash map
|
||||||
&& this._itemRowMap[item.id] == null
|
&& this._rowMap[item.id] == null
|
||||||
// Regular item or standalone note/attachment
|
// Regular item or standalone note/attachment
|
||||||
&& item.isTopLevelItem()) {
|
&& item.isTopLevelItem()) {
|
||||||
let beforeRow = this.rowCount;
|
let beforeRow = this.rowCount;
|
||||||
|
@ -824,7 +821,7 @@ Zotero.ItemTreeView.prototype.notify = Zotero.Promise.coroutine(function* (actio
|
||||||
else if (action == 'modify' && ids.length == 1 &&
|
else if (action == 'modify' && ids.length == 1 &&
|
||||||
savedSelection.length == 1 && savedSelection[0] == ids[0]) {
|
savedSelection.length == 1 && savedSelection[0] == ids[0]) {
|
||||||
// If the item no longer matches the search term, clear the search
|
// If the item no longer matches the search term, clear the search
|
||||||
if (quicksearch && this._itemRowMap[ids[0]] == undefined) {
|
if (quicksearch && this._rowMap[ids[0]] == undefined) {
|
||||||
Zotero.debug('Selected item no longer matches quicksearch -- clearing');
|
Zotero.debug('Selected item no longer matches quicksearch -- clearing');
|
||||||
quicksearch.value = '';
|
quicksearch.value = '';
|
||||||
quicksearch.doCommand();
|
quicksearch.doCommand();
|
||||||
|
@ -847,7 +844,7 @@ Zotero.ItemTreeView.prototype.notify = Zotero.Promise.coroutine(function* (actio
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (previousRow === false) {
|
if (previousRow === false) {
|
||||||
previousRow = this._itemRowMap[ids[0]];
|
previousRow = this._rowMap[ids[0]];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sort) {
|
if (sort) {
|
||||||
|
@ -1116,11 +1113,6 @@ Zotero.ItemTreeView.prototype.isContainer = function(row)
|
||||||
return this.getRow(row).ref.isRegularItem();
|
return this.getRow(row).ref.isRegularItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
Zotero.ItemTreeView.prototype.isContainerOpen = function(row)
|
|
||||||
{
|
|
||||||
return this._rows[row].isOpen;
|
|
||||||
}
|
|
||||||
|
|
||||||
Zotero.ItemTreeView.prototype.isContainerEmpty = function(row)
|
Zotero.ItemTreeView.prototype.isContainerEmpty = function(row)
|
||||||
{
|
{
|
||||||
if (this._sourcesOnly) {
|
if (this._sourcesOnly) {
|
||||||
|
@ -1135,11 +1127,6 @@ Zotero.ItemTreeView.prototype.isContainerEmpty = function(row)
|
||||||
return item.numNotes(includeTrashed) === 0 && item.numAttachments(includeTrashed) == 0;
|
return item.numNotes(includeTrashed) === 0 && item.numAttachments(includeTrashed) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Zotero.ItemTreeView.prototype.getLevel = function(row)
|
|
||||||
{
|
|
||||||
return this.getRow(row).level;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gets the index of the row's container, or -1 if none (top-level)
|
// Gets the index of the row's container, or -1 if none (top-level)
|
||||||
Zotero.ItemTreeView.prototype.getParentIndex = function(row)
|
Zotero.ItemTreeView.prototype.getParentIndex = function(row)
|
||||||
{
|
{
|
||||||
|
@ -1296,13 +1283,13 @@ Zotero.ItemTreeView.prototype.cycleHeader = Zotero.Promise.coroutine(function* (
|
||||||
this.selection.selectEventsSuppressed = true;
|
this.selection.selectEventsSuppressed = true;
|
||||||
var savedSelection = this.getSelectedItems(true);
|
var savedSelection = this.getSelectedItems(true);
|
||||||
if (savedSelection.length == 1) {
|
if (savedSelection.length == 1) {
|
||||||
var pos = this._itemRowMap[savedSelection[0]] - this._treebox.getFirstVisibleRow();
|
var pos = this._rowMap[savedSelection[0]] - this._treebox.getFirstVisibleRow();
|
||||||
}
|
}
|
||||||
yield this.sort();
|
yield this.sort();
|
||||||
yield this.rememberSelection(savedSelection);
|
yield this.rememberSelection(savedSelection);
|
||||||
// If single row was selected, try to keep it in the same place
|
// If single row was selected, try to keep it in the same place
|
||||||
if (savedSelection.length == 1) {
|
if (savedSelection.length == 1) {
|
||||||
var newRow = this._itemRowMap[savedSelection[0]];
|
var newRow = this._rowMap[savedSelection[0]];
|
||||||
// Calculate the last row that would give us a full view
|
// Calculate the last row that would give us a full view
|
||||||
var fullTop = Math.max(0, this._rows.length - this._treebox.getPageLength());
|
var fullTop = Math.max(0, this._rows.length - this._treebox.getPageLength());
|
||||||
// Calculate the row that would give us the same position
|
// Calculate the row that would give us the same position
|
||||||
|
@ -1327,9 +1314,9 @@ Zotero.ItemTreeView.prototype.sort = Zotero.Promise.coroutine(function* (itemID)
|
||||||
this._needsSort = false;
|
this._needsSort = false;
|
||||||
|
|
||||||
// Single child item sort -- just toggle parent closed and open
|
// Single child item sort -- just toggle parent closed and open
|
||||||
if (itemID && this._itemRowMap[itemID] &&
|
if (itemID && this._rowMap[itemID] &&
|
||||||
this.getRow(this._itemRowMap[itemID]).ref.parentKey) {
|
this.getRow(this._rowMap[itemID]).ref.parentKey) {
|
||||||
let parentIndex = this.getParentIndex(this._itemRowMap[itemID]);
|
let parentIndex = this.getParentIndex(this._rowMap[itemID]);
|
||||||
this._closeContainer(parentIndex);
|
this._closeContainer(parentIndex);
|
||||||
yield this.toggleOpenState(parentIndex);
|
yield this.toggleOpenState(parentIndex);
|
||||||
return;
|
return;
|
||||||
|
@ -1537,7 +1524,7 @@ Zotero.ItemTreeView.prototype.sort = Zotero.Promise.coroutine(function* (itemID)
|
||||||
|
|
||||||
// Single-row sort
|
// Single-row sort
|
||||||
if (itemID) {
|
if (itemID) {
|
||||||
let row = this._itemRowMap[itemID];
|
let row = this._rowMap[itemID];
|
||||||
for (let i=0, len=this._rows.length; i<len; i++) {
|
for (let i=0, len=this._rows.length; i<len; i++) {
|
||||||
if (i === row) {
|
if (i === row) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -1604,10 +1591,10 @@ Zotero.ItemTreeView.prototype.selectItem = Zotero.Promise.coroutine(function* (i
|
||||||
|
|
||||||
// If no row map, we're probably in the process of switching collections,
|
// If no row map, we're probably in the process of switching collections,
|
||||||
// so store the item to select on the item group for later
|
// so store the item to select on the item group for later
|
||||||
if (!this._itemRowMap) {
|
if (!this._rowMap) {
|
||||||
if (this.collectionTreeRow) {
|
if (this.collectionTreeRow) {
|
||||||
this.collectionTreeRow.itemToSelect = { id: id, expand: expand };
|
this.collectionTreeRow.itemToSelect = { id: id, expand: expand };
|
||||||
Zotero.debug("_itemRowMap not yet set; not selecting item");
|
Zotero.debug("_rowMap not yet set; not selecting item");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1615,7 +1602,7 @@ Zotero.ItemTreeView.prototype.selectItem = Zotero.Promise.coroutine(function* (i
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var row = this._itemRowMap[id];
|
var row = this._rowMap[id];
|
||||||
|
|
||||||
// Get the row of the parent, if there is one
|
// Get the row of the parent, if there is one
|
||||||
var parentRow = null;
|
var parentRow = null;
|
||||||
|
@ -1627,8 +1614,8 @@ Zotero.ItemTreeView.prototype.selectItem = Zotero.Promise.coroutine(function* (i
|
||||||
}
|
}
|
||||||
|
|
||||||
var parent = item.parentItemID;
|
var parent = item.parentItemID;
|
||||||
if (parent && this._itemRowMap[parent] != undefined) {
|
if (parent && this._rowMap[parent] != undefined) {
|
||||||
parentRow = this._itemRowMap[parent];
|
parentRow = this._rowMap[parent];
|
||||||
}
|
}
|
||||||
|
|
||||||
// If row with id not visible, check to see if it's hidden under a parent
|
// If row with id not visible, check to see if it's hidden under a parent
|
||||||
|
@ -1656,7 +1643,7 @@ Zotero.ItemTreeView.prototype.selectItem = Zotero.Promise.coroutine(function* (i
|
||||||
|
|
||||||
// Open the parent
|
// Open the parent
|
||||||
yield this.toggleOpenState(parentRow);
|
yield this.toggleOpenState(parentRow);
|
||||||
row = this._itemRowMap[id];
|
row = this._rowMap[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function calls nsITreeSelection.select(), which triggers the <tree>'s 'onselect'
|
// This function calls nsITreeSelection.select(), which triggers the <tree>'s 'onselect'
|
||||||
|
@ -1732,7 +1719,7 @@ Zotero.ItemTreeView.prototype.selectItems = function(ids) {
|
||||||
|
|
||||||
var rows = [];
|
var rows = [];
|
||||||
for each(var id in ids) {
|
for each(var id in ids) {
|
||||||
if(this._itemRowMap[id] !== undefined) rows.push(this._itemRowMap[id]);
|
if(this._rowMap[id] !== undefined) rows.push(this._rowMap[id]);
|
||||||
}
|
}
|
||||||
rows.sort(function (a, b) {
|
rows.sort(function (a, b) {
|
||||||
return a - b;
|
return a - b;
|
||||||
|
@ -1867,71 +1854,6 @@ Zotero.ItemTreeView.prototype.setFilter = Zotero.Promise.coroutine(function* (ty
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a tree row to the main array, update the row count, tell the treebox that the row count
|
|
||||||
* changed, and update the row map
|
|
||||||
*
|
|
||||||
* @param {Array} newRows - Array to operate on
|
|
||||||
* @param {Zotero.ItemTreeRow} itemTreeRow
|
|
||||||
* @param {Number} beforeRow - Row index to insert new row before
|
|
||||||
*/
|
|
||||||
Zotero.ItemTreeView.prototype._addRow = function (itemTreeRow, beforeRow) {
|
|
||||||
this._addRowToArray(this._rows, itemTreeRow, beforeRow);
|
|
||||||
this.rowCount++;
|
|
||||||
this._treebox.rowCountChanged(beforeRow, 1);
|
|
||||||
// Increment all rows in map at or above insertion point
|
|
||||||
for (let i in this._itemRowMap) {
|
|
||||||
if (this._itemRowMap[j] >= beforeRow) {
|
|
||||||
this._itemRowMap[j]++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Add new row to map
|
|
||||||
this._itemRowMap[itemTreeRow.id] = beforeRow;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a tree row into a given array
|
|
||||||
*
|
|
||||||
* @param {Array} array - Array to operate on
|
|
||||||
* @param {Zotero.ItemTreeRow} itemTreeRow
|
|
||||||
* @param {Number} beforeRow - Row index to insert new row before
|
|
||||||
*/
|
|
||||||
Zotero.ItemTreeView.prototype._addRowToArray = function (array, itemTreeRow, beforeRow) {
|
|
||||||
array.splice(beforeRow, 0, itemTreeRow);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove a row from the main array, decrement the row count, tell the treebox that the row
|
|
||||||
* count changed, delete the row from the map, and optionally update all rows above it in the map
|
|
||||||
*/
|
|
||||||
Zotero.ItemTreeView.prototype._removeRow = function (row, skipItemMapUpdate) {
|
|
||||||
var id = this._rows[row].id;
|
|
||||||
this._rows.splice(row, 1);
|
|
||||||
this.rowCount--;
|
|
||||||
this._treebox.rowCountChanged(row + 1, -1);
|
|
||||||
delete this._itemRowMap[id];
|
|
||||||
if (!skipItemMapUpdate) {
|
|
||||||
for (let i in this._itemRowMap) {
|
|
||||||
if (this._itemRowMap[i] > row) {
|
|
||||||
this._itemRowMap[i]--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*if (this.selection.isSelected(row)) {
|
|
||||||
this.selection.toggleSelect(row);
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns a reference to the item at row (see Zotero.Item in data_access.js)
|
|
||||||
*/
|
|
||||||
Zotero.ItemTreeView.prototype.getRow = function(row) {
|
|
||||||
return this._rows[row];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create map of item ids to row indexes
|
* Create map of item ids to row indexes
|
||||||
*/
|
*/
|
||||||
|
@ -1946,7 +1868,7 @@ Zotero.ItemTreeView.prototype._refreshItemRowMap = function()
|
||||||
}
|
}
|
||||||
rowMap[id] = i;
|
rowMap[id] = i;
|
||||||
}
|
}
|
||||||
this._itemRowMap = rowMap;
|
this._rowMap = rowMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1972,8 +1894,8 @@ Zotero.ItemTreeView.prototype.rememberSelection = Zotero.Promise.coroutine(funct
|
||||||
}
|
}
|
||||||
for(var i=0; i < selection.length; i++)
|
for(var i=0; i < selection.length; i++)
|
||||||
{
|
{
|
||||||
if (this._itemRowMap[selection[i]] != null) {
|
if (this._rowMap[selection[i]] != null) {
|
||||||
this.selection.toggleSelect(this._itemRowMap[selection[i]]);
|
this.selection.toggleSelect(this._rowMap[selection[i]]);
|
||||||
}
|
}
|
||||||
// Try the parent
|
// Try the parent
|
||||||
else {
|
else {
|
||||||
|
@ -1987,10 +1909,10 @@ Zotero.ItemTreeView.prototype.rememberSelection = Zotero.Promise.coroutine(funct
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._itemRowMap[parent] != null) {
|
if (this._rowMap[parent] != null) {
|
||||||
this._closeContainer(this._itemRowMap[parent]);
|
this._closeContainer(this._rowMap[parent]);
|
||||||
yield this.toggleOpenState(this._itemRowMap[parent]);
|
yield this.toggleOpenState(this._rowMap[parent]);
|
||||||
this.selection.toggleSelect(this._itemRowMap[selection[i]]);
|
this.selection.toggleSelect(this._rowMap[selection[i]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2045,7 +1967,7 @@ Zotero.ItemTreeView.prototype._saveOpenState = function (close) {
|
||||||
Zotero.ItemTreeView.prototype.rememberOpenState = Zotero.Promise.coroutine(function* (itemIDs) {
|
Zotero.ItemTreeView.prototype.rememberOpenState = Zotero.Promise.coroutine(function* (itemIDs) {
|
||||||
var rowsToOpen = [];
|
var rowsToOpen = [];
|
||||||
for each(var id in itemIDs) {
|
for each(var id in itemIDs) {
|
||||||
var row = this._itemRowMap[id];
|
var row = this._rowMap[id];
|
||||||
// Item may not still exist
|
// Item may not still exist
|
||||||
if (row == undefined) {
|
if (row == undefined) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -2111,8 +2033,8 @@ Zotero.ItemTreeView.prototype.saveFirstRow = function() {
|
||||||
|
|
||||||
|
|
||||||
Zotero.ItemTreeView.prototype.rememberFirstRow = function(firstRow) {
|
Zotero.ItemTreeView.prototype.rememberFirstRow = function(firstRow) {
|
||||||
if (firstRow && this._itemRowMap[firstRow]) {
|
if (firstRow && this._rowMap[firstRow]) {
|
||||||
this._treebox.scrollToRow(this._itemRowMap[firstRow]);
|
this._treebox.scrollToRow(this._rowMap[firstRow]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2892,7 +2814,7 @@ Zotero.ItemTreeView.prototype.canDropCheck = function (row, orient, dataTransfer
|
||||||
|
|
||||||
// Don't allow children to be dragged within their own parents
|
// Don't allow children to be dragged within their own parents
|
||||||
var parentItemID = item.parentItemID;
|
var parentItemID = item.parentItemID;
|
||||||
var parentIndex = this._itemRowMap[parentItemID];
|
var parentIndex = this._rowMap[parentItemID];
|
||||||
if (row != -1 && this.getLevel(row) > 0) {
|
if (row != -1 && this.getLevel(row) > 0) {
|
||||||
if (this.getRow(this.getParentIndex(row)).ref.id == parentItemID) {
|
if (this.getRow(this.getParentIndex(row)).ref.id == parentItemID) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -28,6 +28,8 @@ Zotero.LibraryTreeView = function () {
|
||||||
this._listeners = {
|
this._listeners = {
|
||||||
load: []
|
load: []
|
||||||
};
|
};
|
||||||
|
this._rows = [];
|
||||||
|
this._rowMap = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
Zotero.LibraryTreeView.prototype = {
|
Zotero.LibraryTreeView.prototype = {
|
||||||
|
@ -52,6 +54,79 @@ Zotero.LibraryTreeView.prototype = {
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a reference to the tree row at a given row
|
||||||
|
*/
|
||||||
|
getRow: function(row) {
|
||||||
|
return this._rows[row];
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a tree row to the main array, update the row count, tell the treebox that the row
|
||||||
|
* count changed, and update the row map
|
||||||
|
*
|
||||||
|
* @param {Array} newRows - Array to operate on
|
||||||
|
* @param {Zotero.ItemTreeRow} itemTreeRow
|
||||||
|
* @param {Number} [beforeRow] - Row index to insert new row before
|
||||||
|
*/
|
||||||
|
_addRow: function (treeRow, beforeRow) {
|
||||||
|
this._addRowToArray(this._rows, treeRow, beforeRow);
|
||||||
|
this.rowCount++;
|
||||||
|
this._treebox.rowCountChanged(beforeRow, 1);
|
||||||
|
// Increment all rows in map at or above insertion point
|
||||||
|
for (let i in this._rowMap) {
|
||||||
|
if (this._rowMap[i] >= beforeRow) {
|
||||||
|
this._rowMap[i]++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Add new row to map
|
||||||
|
this._rowMap[treeRow.id] = beforeRow;
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a tree row into a given array
|
||||||
|
*
|
||||||
|
* @param {Array} array - Array to operate on
|
||||||
|
* @param {Zotero.CollectionTreeRow|ItemTreeRow} treeRow
|
||||||
|
* @param {Number} beforeRow - Row index to insert new row before
|
||||||
|
*/
|
||||||
|
_addRowToArray: function (array, treeRow, beforeRow) {
|
||||||
|
array.splice(beforeRow, 0, treeRow);
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a row from the main array, decrement the row count, tell the treebox that the row
|
||||||
|
* count changed, delete the row from the map, and optionally update all rows above it in the map
|
||||||
|
*/
|
||||||
|
_removeRow: function (row, skipMapUpdate) {
|
||||||
|
var id = this._rows[row].id;
|
||||||
|
this._rows.splice(row, 1);
|
||||||
|
this.rowCount--;
|
||||||
|
this._treebox.rowCountChanged(row + 1, -1);
|
||||||
|
delete this._rowMap[id];
|
||||||
|
if (!skipMapUpdate) {
|
||||||
|
for (let i in this._rowMap) {
|
||||||
|
if (this._rowMap[i] > row) {
|
||||||
|
this._rowMap[i]--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
getLevel: function (row) {
|
||||||
|
return this._rows[row].level;
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
isContainerOpen: function(row) {
|
||||||
|
return this._rows[row].isOpen;
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called while a drag is over the tree
|
* Called while a drag is over the tree
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -94,5 +94,36 @@ describe("Zotero.CollectionTreeView", function() {
|
||||||
selected = collectionsView.getSelectedCollection(true);
|
selected = collectionsView.getSelectedCollection(true);
|
||||||
assert.equal(selected, id);
|
assert.equal(selected, id);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should add a saved search after collections", function* () {
|
||||||
|
var collection = new Zotero.Collection;
|
||||||
|
collection.name = "Test";
|
||||||
|
var collectionID = yield collection.save();
|
||||||
|
var cv = win.ZoteroPane.collectionsView;
|
||||||
|
|
||||||
|
var search = new Zotero.Search;
|
||||||
|
search.name = "A Test Search";
|
||||||
|
search.addCondition('title', 'contains', 'test');
|
||||||
|
var searchID = yield search.save();
|
||||||
|
|
||||||
|
var collectionRow = cv._rowMap["C" + collectionID];
|
||||||
|
var searchRow = cv._rowMap["S" + searchID];
|
||||||
|
var duplicatesRow = cv._rowMap["D" + Zotero.Libraries.userLibraryID];
|
||||||
|
var unfiledRow = cv._rowMap["U" + Zotero.Libraries.userLibraryID];
|
||||||
|
|
||||||
|
assert.isAbove(searchRow, collectionRow);
|
||||||
|
// If there's a duplicates row or an unfiled row, add before those.
|
||||||
|
// Otherwise, add before the trash
|
||||||
|
if (duplicatesRow !== undefined) {
|
||||||
|
assert.isBelow(searchRow, duplicatesRow);
|
||||||
|
}
|
||||||
|
else if (unfiledRow !== undefined) {
|
||||||
|
assert.isBelow(searchRow, unfiledRow);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var trashRow = cv._rowMap["T" + Zotero.Libraries.userLibraryID];
|
||||||
|
assert.isBelow(searchRow, trashRow);
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue
Block a user