commit d22f762bb69d9738c46a786d5de84aa52afd8311
parent 6328d1f39ba805fef98b5827ef514f10e88b7f08
Author: Dan Stillman <dstillman@zotero.org>
Date: Mon, 4 May 2015 02:22:20 -0400
Add new collection rows without reloading the collections list
Diffstat:
2 files changed, 159 insertions(+), 76 deletions(-)
diff --git a/chrome/content/zotero/xpcom/collectionTreeView.js b/chrome/content/zotero/xpcom/collectionTreeView.js
@@ -56,7 +56,6 @@ Zotero.CollectionTreeView = function()
'collectionTreeView'
);
this._containerState = {};
- this._publicationsRow;
this._duplicateLibraries = [];
this._unfiledLibraries = [];
this._trashNotEmpty = {};
@@ -175,37 +174,41 @@ Zotero.CollectionTreeView.prototype.refresh = Zotero.Promise.coroutine(function*
var newRows = [];
var self = this;
- var library = {
- libraryID: Zotero.Libraries.userLibraryID
- };
//
// Add "My Library"
//
- // addRow(treeRow, level, beforeRow, startOpen)
- this._addRow(newRows, new Zotero.CollectionTreeRow('library', library), 0, 1);
+ this._addRow(
+ newRows,
+ new Zotero.CollectionTreeRow('library', { libraryID: Zotero.Libraries.userLibraryID })
+ );
yield this._expandRow(newRows, 0);
- // Add "My Publications"
this._addRow(newRows, new Zotero.CollectionTreeRow('separator', false));
- this._addRow(newRows, new Zotero.CollectionTreeRow('publications', {
- libraryID: Zotero.Libraries.publicationsLibraryID
- }));
- this._publicationsRow = newRows.length - 1;
+
+ // Add "My Publications"
+ this._addRow(
+ newRows,
+ new Zotero.CollectionTreeRow('publications', {
+ libraryID: Zotero.Libraries.publicationsLibraryID
+ })
+ );
// Add groups
var groups = yield Zotero.Groups.getAll();
if (groups.length) {
this._addRow(newRows, new Zotero.CollectionTreeRow('separator', false));
- var row = this._addRow(newRows, new Zotero.CollectionTreeRow('header', {
- id: "group-libraries-header",
- label: Zotero.getString('pane.collections.groupLibraries'),
- libraryID: -1
- }, 0));
+ var row = this._addRow(
+ newRows,
+ new Zotero.CollectionTreeRow('header', {
+ id: "group-libraries-header",
+ label: Zotero.getString('pane.collections.groupLibraries'),
+ libraryID: -1
+ }, 0)
+ );
for (let i = 0, len = groups.length; i < len; i++) {
- var row = this._addRow(
- newRows,
- new Zotero.CollectionTreeRow('group', groups[i])
+ this._rowMap['L' + groups[i].libraryID] = this._addRow(
+ newRows, new Zotero.CollectionTreeRow('group', groups[i])
);
}
}
@@ -213,7 +216,7 @@ Zotero.CollectionTreeView.prototype.refresh = Zotero.Promise.coroutine(function*
this.selection.clearSelection();
this._rows = newRows;
this.rowCount = this._rows.length;
- this._refreshCollectionRowMap();
+ this._refreshRowMap();
var diff = this.rowCount - oldCount;
if (diff != 0) {
@@ -285,10 +288,6 @@ Zotero.CollectionTreeView.prototype.notify = Zotero.Promise.coroutine(function*
break;
case 'group':
- //if (this._rowMap['G' + ids[i]] != null) {
- // rows.push(this._rowMap['G' + ids[i]]);
- //}
-
// For now, just reload if a group is removed, since otherwise
// we'd have to remove collections too
yield this.reload();
@@ -308,7 +307,7 @@ Zotero.CollectionTreeView.prototype.notify = Zotero.Promise.coroutine(function*
this._treebox.rowCountChanged(row, -1);
}
- this._refreshCollectionRowMap();
+ this._refreshRowMap();
}
if (!this.selection.count) {
@@ -346,59 +345,128 @@ Zotero.CollectionTreeView.prototype.notify = Zotero.Promise.coroutine(function*
{
// Multiple adds not currently supported
let id = ids[0];
+ let selectRow = !extraData[id] || !extraData[id].skipSelect;
switch (type)
{
case 'collection':
- var collection = yield Zotero.Collections.getAsync(id);
-
- // Open container if creating subcollection
- var parentID = collection.parentID;
- if (parentID) {
- if (!this.isContainerOpen(this._collectionRowMap[parentID])){
- this.toggleOpenState(this._collectionRowMap[parentID]);
- }
- }
+ case 'search':
+ yield this._addSortedRow(type, id);
- yield this.reload();
if (Zotero.suppressUIUpdates) {
this.rememberSelection(savedSelection);
break;
}
- let row = this._collectionRowMap[collection.id];
- if (!extraData[id] || !extraData[id].skipSelect) {
- this._treebox.ensureRowIsVisible(row);
- this.selection.select(row);
- }
- break;
- case 'search':
- yield this.reload();
- if (Zotero.suppressUIUpdates) {
- this.rememberSelection(savedSelection);
- break;
- }
- if (!extraData[id] || !extraData[id].skipSelect) {
- this.selection.select(this._rowMap['S' + id]);
+ if (selectRow) {
+ if (type == 'collection') {
+ yield this.selectCollection(id);
+ }
+ else if (type == 'search') {
+ this.selection.select(this._rowMap['S' + id]);
+ }
}
+
break;
-
+
case 'group':
yield this.reload();
// Groups can only be created during sync
this.rememberSelection(savedSelection);
break;
-
- case 'bucket':
- yield this.reload();
- this.rememberSelection(savedSelection);
- break;
}
}
this.selection.selectEventsSuppressed = false;
});
+/**
+ * Add a row in the appropriate place
+ *
+ * This only adds a row if it would be visible without opening any containers
+ */
+Zotero.CollectionTreeView.prototype._addSortedRow = Zotero.Promise.coroutine(function* (objectType, id) {
+ if (objectType == 'collection') {
+ let collection = yield Zotero.Collections.getAsync(id);
+
+ let parentID = collection.parentID;
+
+ // If parent isn't visible, don't add
+ if (parentID && this._collectionRowMap[parentID] === undefined) {
+ return false;
+ }
+
+ let libraryID = collection.libraryID;
+ let startRow;
+ if (parentID) {
+ startRow = this._collectionRowMap[parentID];
+ }
+ else {
+ startRow = this._rowMap['L' + libraryID];
+ }
+
+ // If container isn't open, don't add
+ if (!this.isContainerOpen(startRow)) {
+ return false;
+ }
+
+ let level = this.getLevel(startRow) + 1;
+ let beforeRow;
+ // If container is empty, just add after
+ if (this.isContainerEmpty(startRow)) {
+ beforeRow = startRow + 1;
+ }
+ else {
+ // Get all collections at the same level that don't have a different parent
+ startRow++;
+ for (let i = startRow; i < this.rowCount; i++) {
+ let treeRow = this.getRow(i);
+ beforeRow = i;
+
+ // If we've moved on to a different library, a different object
+ // type, a different parent at the same or higher level, or a
+ // collection that sorts after, add row first
+ if (!treeRow.isCollection()) {
+ break;
+ }
+
+ let rowLevel = this.getLevel(i);
+ if (rowLevel < level) {
+ break;
+ }
+ else {
+ // Fast forward through subcollections
+ while (rowLevel > level) {
+ beforeRow = ++i;
+ if (i == this.rowCount) {
+ break;
+ }
+ treeRow = this.getRow(i);
+ rowLevel = this.getLevel(i);
+ }
+
+ if (Zotero.localeCompare(treeRow.ref.name, collection.name) > 0) {
+ break;
+ }
+ }
+ }
+ this._addRow(
+ this._rows,
+ new Zotero.CollectionTreeRow('collection', collection),
+ level,
+ beforeRow
+ );
+ this.rowCount++;
+ this._treebox.rowCountChanged(beforeRow, 1);
+ this._refreshRowMap();
+ }
+ }
+ else if (objectType == 'search') {
+ yield this.reload();
+ }
+ return true;
+});
+
/*
* Set the rows that should be highlighted -- actual highlighting is done
@@ -416,9 +484,6 @@ Zotero.CollectionTreeView.prototype.setHighlightedRows = Zotero.Promise.coroutin
yield this.expandToCollection(id);
row = this._collectionRowMap[id];
}
- else if (id == 'P') {
- row = this._publicationsRow;
- }
if (row) {
this._highlightedRows[row] = true;
this._treebox.invalidateRow(row);
@@ -602,7 +667,7 @@ Zotero.CollectionTreeView.prototype.toggleOpenState = Zotero.Promise.coroutine(f
this._rows[row][1] = !this._rows[row][1];
this._treebox.invalidateRow(row);
//this._treebox.endUpdateBatch();
- this._refreshCollectionRowMap();
+ this._refreshRowMap();
yield this._rememberOpenStates();
});
@@ -717,6 +782,13 @@ Zotero.CollectionTreeView.prototype.expandToCollection = Zotero.Promise.coroutin
Zotero.debug("Cannot expand to nonexistent collection " + collectionID, 2);
return false;
}
+
+ // Open library if closed
+ var libraryRow = this._rowMap['L' + col.libraryID];
+ if (!this.isContainerOpen(libraryRow)) {
+ yield this.toggleOpenState(libraryRow);
+ }
+
var row = this._collectionRowMap[collectionID];
if (row) {
return true;
@@ -782,6 +854,22 @@ Zotero.CollectionTreeView.prototype.selectLibrary = function (libraryID) {
}
+Zotero.CollectionTreeView.prototype.selectCollection = Zotero.Promise.coroutine(function* (collectionID) {
+ if (Zotero.suppressUIUpdates) {
+ Zotero.debug("UI updates suppressed -- not changing collection selection");
+ return false;
+ }
+
+ var found = yield this.expandToCollection(collectionID);
+ if (!found) {
+ return;
+ }
+ var row = this._collectionRowMap[collectionID];
+ this._treebox.ensureRowIsVisible(row);
+ this.selection.select(row);
+});
+
+
Zotero.CollectionTreeView.prototype.selectTrash = function (libraryID) {
if (Zotero.suppressUIUpdates) {
Zotero.debug("UI updates suppressed -- not changing library selection");
@@ -917,7 +1005,7 @@ Zotero.CollectionTreeView.prototype.deleteSelection = Zotero.Promise.coroutine(f
yield this.toggleOpenState(i);
}
}
- this._refreshCollectionRowMap();
+ this._refreshRowMap();
//create an array of collections
var rows = new Array();
@@ -1175,19 +1263,18 @@ Zotero.CollectionTreeView.prototype.rememberSelection = Zotero.Promise.coroutine
/**
* Creates mapping of item group ids to tree rows
*/
-Zotero.CollectionTreeView.prototype._refreshCollectionRowMap = function()
-{
- this._collectionRowMap = [];
- this._rowMap = [];
- for(var i = 0, len = this.rowCount; i < len; i++) {
- var treeRow = this.getRow(i);
+Zotero.CollectionTreeView.prototype._refreshRowMap = function() {
+ this._rowMap = {};
+ this._collectionRowMap = {};
+ for (let i = 0, len = this.rowCount; i < len; i++) {
+ let treeRow = this.getRow(i);
+
+ this._rowMap[treeRow.id] = i;
// Collections get special treatment for now
if (treeRow.isCollection()) {
this._collectionRowMap[treeRow.ref.id] = i;
}
-
- this._rowMap[treeRow.id] = i;
}
}
@@ -2089,7 +2176,9 @@ Zotero.CollectionTreeRow = function(type, ref)
Zotero.CollectionTreeRow.prototype.__defineGetter__('id', function () {
switch (this.type) {
case 'library':
- return 'L';
+ case 'publications':
+ case 'group':
+ return 'L' + this.ref.libraryID;
case 'collection':
return 'C' + this.ref.id;
@@ -2097,9 +2186,6 @@ Zotero.CollectionTreeRow.prototype.__defineGetter__('id', function () {
case 'search':
return 'S' + this.ref.id;
- case 'publications':
- return 'P';
-
case 'duplicates':
return 'D' + this.ref.libraryID;
@@ -2114,9 +2200,6 @@ Zotero.CollectionTreeRow.prototype.__defineGetter__('id', function () {
return 'HG';
}
break;
-
- case 'group':
- return 'G' + this.ref.id;
}
return '';
diff --git a/chrome/content/zotero/xpcom/data/collection.js b/chrome/content/zotero/xpcom/data/collection.js
@@ -342,7 +342,7 @@ Zotero.Collection.prototype._saveData = Zotero.Promise.coroutine(function* (env)
this.libraryID, this.parentKey
));
}
- if (this.id) {
+ if (!isNew) {
Zotero.Notifier.trigger('move', 'collection', this.id);
}
env.parentIDs = parentIDs;