diff --git a/chrome/content/zotero/xpcom/collectionTreeView.js b/chrome/content/zotero/xpcom/collectionTreeView.js index 8afb27caab..e56fad337c 100644 --- a/chrome/content/zotero/xpcom/collectionTreeView.js +++ b/chrome/content/zotero/xpcom/collectionTreeView.js @@ -41,10 +41,11 @@ Zotero.CollectionTreeView = function() this._treebox = null; this._highlightedRows = {}; - this._unregisterID = Zotero.Notifier.registerObserver(this, ['collection', 'search', 'share', 'group', 'bucket']); + this._unregisterID = Zotero.Notifier.registerObserver(this, ['collection', 'search', 'share', 'group', 'trash', 'bucket']); this._containerState = {}; this._duplicateLibraries = []; this._unfiledLibraries = []; + this._trashNotEmpty = {}; } /* @@ -148,7 +149,6 @@ Zotero.CollectionTreeView.prototype.refresh = function() var self = this; var library = { - id: null, libraryID: null }; @@ -256,11 +256,14 @@ Zotero.CollectionTreeView.prototype.notify = function(action, type, ids) return; } + if (action == 'refresh' && type == 'trash') { + this._trashNotEmpty[ids[0]] = !!Zotero.Items.getDeleted(ids[0]).length; + return; + } + this.selection.selectEventsSuppressed = true; var savedSelection = this.saveSelection(); - var madeChanges = false; - if (action == 'delete') { var selectedIndex = this.selection.count ? this.selection.selectedIndex : 0; @@ -432,20 +435,20 @@ Zotero.CollectionTreeView.prototype.getCellText = function(row, column) Zotero.CollectionTreeView.prototype.getImageSrc = function(row, col) { - var source = this._getItemAtRow(row); - var collectionType = source.type; + var itemGroup = this._getItemAtRow(row); + var collectionType = itemGroup.type; switch (collectionType) { case 'trash': - if (this.trashNotEmpty) { + if (this._trashNotEmpty[itemGroup.ref.libraryID ? itemGroup.ref.libraryID : 0]) { collectionType += '-full'; } break; case 'header': - if (source.ref.id == 'group-libraries-header') { + if (itemGroup.ref.id == 'group-libraries-header') { collectionType = 'groups'; } - else if (source.ref.id == 'commons-header') { + else if (itemGroup.ref.id == 'commons-header') { collectionType = 'commons'; } break; @@ -490,11 +493,13 @@ Zotero.CollectionTreeView.prototype.isContainerEmpty = function(row) } if (itemGroup.isGroup()) { var libraryID = itemGroup.ref.libraryID; + libraryID = (libraryID ? libraryID : 0) + ''; return !itemGroup.ref.hasCollections() && !itemGroup.ref.hasSearches() - && this._duplicateLibraries.indexOf(libraryID + '') == -1 - && this._unfiledLibraries.indexOf(libraryID + '') == -1; + && this._duplicateLibraries.indexOf(libraryID) == -1 + && this._unfiledLibraries.indexOf(libraryID) == -1 + && this.hideSources.indexOf('trash') != -1; } if (itemGroup.isCollection()) { return !itemGroup.ref.hasChildCollections(); @@ -819,17 +824,16 @@ Zotero.CollectionTreeView.prototype._expandRow = function (row, forceOpen) { if (isGroup) { var group = Zotero.Groups.getByLibraryID(libraryID); var collections = group.getCollections(); - var showTrash = false; } else { var collections = Zotero.getCollections(itemGroup.ref.id); - var showTrash = this.hideSources.indexOf('trash') == -1; } var savedSearches = Zotero.Searches.getAll(libraryID); var showDuplicates = this.hideSources.indexOf('duplicates') == -1 && this._duplicateLibraries.indexOf(intLibraryID + '') != -1; var showUnfiled = this._unfiledLibraries.indexOf(intLibraryID + '') != -1; + var showTrash = this.hideSources.indexOf('trash') == -1; // If not a manual open and either the library is set to be hidden // or this is a collection that isn't explicitly opened, @@ -841,7 +845,7 @@ Zotero.CollectionTreeView.prototype._expandRow = function (row, forceOpen) { return 0; } - var startOpen = !!(collections.length || savedSearches.length || showDuplicates || showUnfiled); + var startOpen = !!(collections.length || savedSearches.length || showDuplicates || showUnfiled || showTrash); // If this isn't a manual open, set the initial state depending on whether // there are child nodes @@ -881,7 +885,7 @@ Zotero.CollectionTreeView.prototype._expandRow = function (row, forceOpen) { // Duplicate items if (showDuplicates) { - var d = new Zotero.Duplicates(isGroup ? group.libraryID : 0); + var d = new Zotero.Duplicates(intLibraryID); this._showRow(new Zotero.ItemGroup('duplicates', d), level, row + 1 + newRows); newRows++; } @@ -890,22 +894,25 @@ Zotero.CollectionTreeView.prototype._expandRow = function (row, forceOpen) { if (showUnfiled) { var s = new Zotero.Search; if (isGroup) { - s.libraryID = group.libraryID; + s.libraryID = libraryID; } s.name = Zotero.getString('pane.collections.unfiled'); - s.addCondition('libraryID', 'is', isGroup ? group.libraryID : null); + s.addCondition('libraryID', 'is', libraryID); s.addCondition('unfiled', 'true'); this._showRow(new Zotero.ItemGroup('unfiled', s), level, row + 1 + newRows); newRows++; } if (showTrash) { - var deletedItems = Zotero.Items.getDeleted(); - if (deletedItems || Zotero.Prefs.get("showTrashWhenEmpty")) { - this._showRow(new Zotero.ItemGroup('trash', false), level, row + 1 + newRows); + var deletedItems = Zotero.Items.getDeleted(libraryID); + if (deletedItems.length || Zotero.Prefs.get("showTrashWhenEmpty")) { + var ref = { + libraryID: libraryID + }; + this._showRow(new Zotero.ItemGroup('trash', ref), level, row + 1 + newRows); newRows++; } - this.trashNotEmpty = !!deletedItems; + this._trashNotEmpty[intLibraryID] = !!deletedItems.length; } return newRows; @@ -1785,7 +1792,7 @@ Zotero.ItemGroup.prototype.__defineGetter__('id', function () { return 'U' + (this.ref.libraryID ? this.ref.libraryID : 0); case 'trash': - return 'T'; + return 'T' + (this.ref.libraryID ? this.ref.libraryID : 0); case 'header': if (this.ref.id == 'group-libraries-header') { @@ -2005,6 +2012,7 @@ Zotero.ItemGroup.prototype.getSearchObject = function() { includeScopeChildren = true; } else if (this.isTrash()) { + s.addCondition('libraryID', 'is', this.ref.libraryID); s.addCondition('deleted', 'true'); } else { diff --git a/chrome/content/zotero/xpcom/data/item.js b/chrome/content/zotero/xpcom/data/item.js index 8c41f86c11..855e100a05 100644 --- a/chrome/content/zotero/xpcom/data/item.js +++ b/chrome/content/zotero/xpcom/data/item.js @@ -2053,7 +2053,7 @@ Zotero.Item.prototype.save = function() { } } // Refresh trash - Zotero.Notifier.trigger('refresh', 'collection', 0); + Zotero.Notifier.trigger('refresh', 'trash', this.libraryID ? this.libraryID : 0); if (this._deleted) { Zotero.Notifier.trigger('trash', 'item', this.id); } diff --git a/chrome/content/zotero/xpcom/data/items.js b/chrome/content/zotero/xpcom/data/items.js index 29c9e29797..fcdadf58ce 100644 --- a/chrome/content/zotero/xpcom/data/items.js +++ b/chrome/content/zotero/xpcom/data/items.js @@ -125,16 +125,34 @@ Zotero.Items = new function() { /** * Return items marked as deleted * - * @param {Boolean} asIDs Return itemIDs instead of + * @param {Number|NULL} libraryID + * @param {Boolean} asIDs Return itemIDs instead of * Zotero.Item objects - * @return {Zotero.Item[]|Integer[]} + * @return {Zotero.Item[]|Integer[]} */ - this.getDeleted = function (asIDs, days) { - var sql = "SELECT itemID FROM deletedItems"; - if (days) { - sql += " WHERE dateDeleted<=DATE('NOW', '-" + parseInt(days) + " DAYS')"; + this.getDeleted = function (libraryID, asIDs, days) { + // Throw warning for pre-3.0b3 arguments + if (typeof libraryID == 'boolean') { + throw new Error("libraryID must be a number or null"); + } + + var sql = "SELECT itemID FROM items JOIN deletedItems USING (itemID) " + + "WHERE libraryID" + (libraryID ? "=?" : " IS NULL"); + + if (days) { + sql += " AND dateDeleted<=DATE('NOW', '-" + parseInt(days) + " DAYS')"; + } + + if (libraryID) { + var ids = Zotero.DB.columnQuery(sql, [libraryID]); + } + else { + var ids = Zotero.DB.columnQuery(sql); + } + + if (!ids) { + return []; } - var ids = Zotero.DB.columnQuery(sql); if (asIDs) { return ids; } @@ -467,15 +485,15 @@ Zotero.Items = new function() { /** * @param {Integer} days Only delete items deleted more than this many days ago */ - this.emptyTrash = function (days) { + this.emptyTrash = function (libraryID, days) { Zotero.DB.beginTransaction(); - var deletedIDs = this.getDeleted(true, days); - if (deletedIDs) { + var deletedIDs = this.getDeleted(libraryID, true, days); + if (deletedIDs.length) { this.erase(deletedIDs); - Zotero.Notifier.trigger('refresh', 'collection', 0); + Zotero.Notifier.trigger('refresh', 'collection', libraryID ? libraryID : 0); } Zotero.DB.commitTransaction(); - return deletedIDs ? deletedIDs.length : 0; + return deletedIDs.length; } diff --git a/chrome/content/zotero/xpcom/itemTreeView.js b/chrome/content/zotero/xpcom/itemTreeView.js index 7c23f11fed..c4e60c7513 100644 --- a/chrome/content/zotero/xpcom/itemTreeView.js +++ b/chrome/content/zotero/xpcom/itemTreeView.js @@ -1546,10 +1546,7 @@ Zotero.ItemTreeView.prototype.deleteSelection = function (force) else if (itemGroup.isTrash()) { Zotero.Items.erase(ids); } - else if (itemGroup.isGroup() || (force && itemGroup.isWithinGroup())) { - Zotero.Items.erase(ids); - } - else if (itemGroup.isLibrary() || force) { + else if (itemGroup.isLibrary(true) || force) { Zotero.Items.trash(ids); } else if (itemGroup.isCollection()) { diff --git a/chrome/content/zotero/xpcom/notifier.js b/chrome/content/zotero/xpcom/notifier.js index 14fab27df4..dbade2ce42 100644 --- a/chrome/content/zotero/xpcom/notifier.js +++ b/chrome/content/zotero/xpcom/notifier.js @@ -28,7 +28,7 @@ Zotero.Notifier = new function(){ var _disabled = false; var _types = [ 'collection', 'creator', 'search', 'share', 'share-items', 'item', - 'collection-item', 'item-tag', 'tag', 'group', 'bucket', 'relation' + 'collection-item', 'item-tag', 'tag', 'group', 'trash', 'bucket', 'relation' ]; var _inTransaction; var _locked = false; @@ -277,7 +277,7 @@ Zotero.Notifier = new function(){ } } - if (runQueue[type][event].ids.length) { + if (runQueue[type][event].ids.length || event == 'refresh') { totals += ' [' + event + '-' + type + ': ' + runQueue[type][event].ids.length + ']'; } } @@ -290,7 +290,7 @@ Zotero.Notifier = new function(){ for (var type in runQueue) { for (var event in runQueue[type]) { - if (runQueue[type][event].ids.length) { + if (runQueue[type][event].ids.length || event == 'refresh') { trigger(event, type, runQueue[type][event].ids, runQueue[type][event].data, true); } diff --git a/chrome/content/zotero/xpcom/zotero.js b/chrome/content/zotero/xpcom/zotero.js index 98a68b5040..ec9cb09861 100644 --- a/chrome/content/zotero/xpcom/zotero.js +++ b/chrome/content/zotero/xpcom/zotero.js @@ -1383,7 +1383,7 @@ if(appInfo.platformVersion[0] >= 2) { var returns = []; for (var i=0; i 0 && this.collectionsView.selection.currentIndex != -1) { - var itemGroup = this.collectionsView._getItemAtRow(this.collectionsView.selection.currentIndex); + + var itemGroup = this.getItemGroup(); if (itemGroup && itemGroup.isGroup()) { return asID ? itemGroup.ref.id : itemGroup.ref; }