Addresses #513, Deleted Items folder

Adds handling for parent/child items in trash -- non-deleted context items will appear in gray, and "Restore to Library" and the delete keystrokes won't be available if any of those are selected

Like other search views, Select All will select only the deleted items
This commit is contained in:
Dan Stillman 2009-01-29 01:14:46 +00:00
parent cb8e226ae9
commit 5e774efc42
5 changed files with 126 additions and 43 deletions

View file

@ -819,6 +819,7 @@ var ZoteroPane = new function()
}
}
function itemSelected()
{
if (!Zotero.stateCheck()) {
@ -829,7 +830,8 @@ var ZoteroPane = new function()
// Display restore button if items selected in Trash
if (this.itemsView && this.itemsView.selection.count) {
document.getElementById('zotero-item-restore-button').hidden
= !this.itemsView._itemGroup.isTrash();
= !this.itemsView._itemGroup.isTrash()
|| _nonDeletedItemsSelected(this.itemsView);
}
var tabs = document.getElementById('zotero-view-tabs');
@ -913,7 +915,27 @@ var ZoteroPane = new function()
label.value = Zotero.getString('pane.item.selected.zero');
}
}
}
/**
* Check if any selected items in the passed (trash) treeview are not deleted
*
* @param {nsITreeView}
* @return {Boolean}
*/
function _nonDeletedItemsSelected(itemsView) {
var start = {};
var end = {};
for (var i=0, len=itemsView.selection.getRangeCount(); i<len; i++) {
itemsView.selection.getRangeAt(i, start, end);
for (var j=start.value; j<=end.value; j++) {
if (!itemsView._getItemAtRow(j).ref.deleted) {
return true;
}
}
}
return false;
}
@ -973,6 +995,19 @@ var ZoteroPane = new function()
this.itemsView._itemGroup.isShare()) {
return;
}
// Do nothing in trash view if any non-deleted items are selected
else if (this.itemsView._itemGroup.isTrash()) {
var start = {};
var end = {};
for (var i=0, len=this.itemsView.selection.getRangeCount(); i<len; i++) {
this.itemsView.selection.getRangeAt(i, start, end);
for (var j=start.value; j<=end.value; j++) {
if (!this.itemsView._getItemAtRow(j).ref.deleted) {
return;
}
}
}
}
}
var eraseChildren = {value: true};
@ -981,15 +1016,16 @@ var ZoteroPane = new function()
var hasChildren;
if (!this.getSelectedCollection()) {
var start = new Object();
var end = new Object();
var start = {};
var end = {};
for (var i=0, len=this.itemsView.selection.getRangeCount(); i<len; i++) {
this.itemsView.selection.getRangeAt(i,start,end);
for (var j=start.value; j<=end.value; j++)
this.itemsView.selection.getRangeAt(i, start, end);
for (var j=start.value; j<=end.value; j++) {
if (this.itemsView._getItemAtRow(j).numChildren()) {
hasChildren = true;
break;
}
}
}
}

View file

@ -1170,8 +1170,7 @@ Zotero.ItemGroup.prototype.setTags = function(tags)
* Returns TRUE if saved search, quicksearch or tag filter
*/
Zotero.ItemGroup.prototype.isSearchMode = function() {
// Search
if (this.isSearch()) {
if (this.isSearch() || this.isTrash()) {
return true;
}

View file

@ -269,13 +269,15 @@ Zotero.Item.prototype.loadPrimaryData = function(allowFail) {
break;
case 'numNotes':
colSQL = '(SELECT COUNT(*) FROM itemNotes '
+ 'WHERE sourceItemID=I.itemID) AS numNotes';
colSQL = '(SELECT COUNT(*) FROM itemNotes INo '
+ 'WHERE sourceItemID=I.itemID AND INo.itemID '
+ 'NOT IN (SELECT itemID FROM deletedItems)) AS numNotes';
break;
case 'numAttachments':
colSQL = '(SELECT COUNT(*) FROM itemAttachments '
+ 'WHERE sourceItemID=I.itemID) AS numAttachments';
colSQL = '(SELECT COUNT(*) FROM itemAttachments IA '
+ 'WHERE sourceItemID=I.itemID AND IA.itemID '
+ 'NOT IN (SELECT itemID FROM deletedItems)) AS numAttachments';
break;
}
if (colSQL) {
@ -326,7 +328,15 @@ Zotero.Item.prototype.loadFromRow = function(row, reload) {
// Only accept primary field data through loadFromRow()
if (this.isPrimaryField(col)) {
//Zotero.debug("Setting field '" + col + "' to '" + row[col] + "' for item " + this.id);
this['_' + col] = row[col] ? row[col] : '';
switch (col) {
case 'numNotes':
case 'numAttachments':
this['_' + col] = row[col] ? parseInt(row[col]) : 0;
break;
default:
this['_' + col] = row[col] ? row[col] : '';
}
}
else {
Zotero.debug(col + ' is not a valid primary field');
@ -1895,8 +1905,8 @@ Zotero.Item.prototype.isRegularItem = function() {
}
Zotero.Item.prototype.numChildren = function() {
return this.numNotes() + this.numAttachments();
Zotero.Item.prototype.numChildren = function(includeTrashed) {
return this.numNotes(includeTrashed) + this.numAttachments(includeTrashed);
}
@ -1996,9 +2006,12 @@ Zotero.Item.prototype.updateNote = function(text) {
/**
* Returns number of notes in item
**/
Zotero.Item.prototype.numNotes = function() {
* Returns number of child notes of item
*
* @param {Boolean} includeTrashed Include trashed child items in count
* @return {Integer}
*/
Zotero.Item.prototype.numNotes = function(includeTrashed) {
if (this.isNote()) {
throw ("numNotes() cannot be called on items of type 'note'");
}
@ -2007,7 +2020,14 @@ Zotero.Item.prototype.numNotes = function() {
return 0;
}
return this._numNotes;
var deleted = 0;
if (includeTrashed) {
var sql = "SELECT COUNT(*) FROM itemNotes WHERE sourceItemID=? AND "
+ "itemID IN (SELECT itemID FROM deletedItems)";
deleted = parseInt(Zotero.DB.valueQuery(sql, this.id));
}
return this._numNotes + deleted;
}
@ -2121,9 +2141,12 @@ Zotero.Item.prototype.setNote = function(text) {
/**
* Returns an array of note itemIDs for this item
**/
Zotero.Item.prototype.getNotes = function() {
* Returns child notes of this item
*
* @param {Boolean} includeTrashed Include trashed child items
* @return {Integer[]} Array of itemIDs, or FALSE if none
*/
Zotero.Item.prototype.getNotes = function(includeTrashed) {
if (this.isNote()) {
throw ("getNotes() cannot be called on items of type 'note'");
}
@ -2134,6 +2157,9 @@ Zotero.Item.prototype.getNotes = function() {
var sql = "SELECT N.itemID, title FROM itemNotes N NATURAL JOIN items "
+ "WHERE sourceItemID=?";
if (!includeTrashed) {
sql += " AND N.itemID NOT IN (SELECT itemID FROM deletedItems)";
}
if (Zotero.Prefs.get('sortNotesChronologically')) {
sql += " ORDER BY dateAdded";
@ -2191,9 +2217,12 @@ Zotero.Item.prototype.isAttachment = function() {
/**
* Returns number of files in item
**/
Zotero.Item.prototype.numAttachments = function() {
* Returns number of child attachments of item
*
* @param {Boolean} includeTrashed Include trashed child items in count
* @return {Integer}
*/
Zotero.Item.prototype.numAttachments = function(includeTrashed) {
if (this.isAttachment()) {
throw ("numAttachments() cannot be called on attachment items");
}
@ -2202,7 +2231,14 @@ Zotero.Item.prototype.numAttachments = function() {
return 0;
}
return this._numAttachments;
var deleted = 0;
if (includeTrashed) {
var sql = "SELECT COUNT(*) FROM itemAttachments WHERE sourceItemID=? AND "
+ "itemID IN (SELECT itemID FROM deletedItems)";
deleted = parseInt(Zotero.DB.valueQuery(sql, this.id));
}
return this._numAttachments + deleted;
}
@ -2680,10 +2716,12 @@ Zotero.Item.prototype.__defineGetter__('attachmentModificationTime', function ()
/**
* Returns an array of attachment itemIDs that have this item as a source,
* or FALSE if none
**/
Zotero.Item.prototype.getAttachments = function() {
* Returns child attachments of this item
*
* @param {Boolean} includeTrashed Include trashed child items
* @return {Integer[]} Array of itemIDs, or FALSE if none
*/
Zotero.Item.prototype.getAttachments = function(includeTrashed) {
if (this.isAttachment()) {
throw ("getAttachments() cannot be called on attachment items");
}
@ -2698,6 +2736,9 @@ Zotero.Item.prototype.getAttachments = function() {
+ "LEFT JOIN itemDataValues IDV "
+ "ON (ID.valueID=IDV.valueID) "
+ "WHERE sourceItemID=?";
if (!includeTrashed) {
sql += " AND A.itemID NOT IN (SELECT itemID FROM deletedItems)";
}
if (Zotero.Prefs.get('sortAttachmentsChronologically')) {
sql += " ORDER BY dateAdded";

View file

@ -567,8 +567,10 @@ Zotero.Items = new function() {
// Should be the same as parts in Zotero.Item.loadPrimaryData
var sql = 'SELECT I.*, '
+ getFirstCreatorSQL() + ', '
+ "(SELECT COUNT(*) FROM itemNotes WHERE sourceItemID=I.itemID) AS numNotes, "
+ "(SELECT COUNT(*) FROM itemAttachments WHERE sourceItemID=I.itemID) AS numAttachments "
+ "(SELECT COUNT(*) FROM itemNotes INo WHERE sourceItemID=I.itemID AND "
+ "INo.itemID NOT IN (SELECT itemID FROM deletedItems)) AS numNotes, "
+ "(SELECT COUNT(*) FROM itemAttachments IA WHERE sourceItemID=I.itemID AND "
+ "IA.itemID NOT IN (SELECT itemID FROM deletedItems)) AS numAttachments "
+ 'FROM items I WHERE 1';
if (arguments[0]) {
sql += ' AND I.itemID IN (' + Zotero.join(arguments[0], ',') + ')';

View file

@ -586,7 +586,7 @@ Zotero.ItemTreeView.prototype.getCellText = function(row, column)
if(column.id == "zotero-items-column-numChildren")
{
var c = obj.numChildren();
var c = obj.numChildren(this._itemGroup.isTrash());
// Don't display '0'
if(c && parseInt(c) > 0) {
val = c;
@ -668,7 +668,9 @@ Zotero.ItemTreeView.prototype.isContainerEmpty = function(row)
if(this._sourcesOnly) {
return true;
} else {
return (this._getItemAtRow(row).numNotes() == 0 && this._getItemAtRow(row).numAttachments() == 0);
var includeTrashed = this._itemGroup.isTrash();
return (this._getItemAtRow(row).numNotes(includeTrashed) == 0
&& this._getItemAtRow(row).numAttachments(includeTrashed) == 0);
}
}
@ -727,8 +729,9 @@ Zotero.ItemTreeView.prototype.toggleOpenState = function(row, skipItemMapRefresh
else {
var item = this._getItemAtRow(row).ref;
//Get children
var attachments = item.getAttachments();
var notes = item.getNotes();
var includeTrashed = this._itemGroup.isTrash();
var attachments = item.getAttachments(includeTrashed);
var notes = item.getNotes(includeTrashed);
var newRows;
if(attachments && notes)
@ -891,6 +894,8 @@ Zotero.ItemTreeView.prototype.sort = function(itemID)
return field;
}
var includeTrashed = this._itemGroup.isTrash();
function rowSort(a,b) {
var cmp, fieldA, fieldB;
@ -915,7 +920,7 @@ Zotero.ItemTreeView.prototype.sort = function(itemID)
break;
case 'numChildren':
cmp = b.numChildren() - a.numChildren();
cmp = b.numChildren(includeTrashed) - a.numChildren(includeTrashed);
if (cmp) {
return cmp;
}
@ -2273,26 +2278,26 @@ Zotero.ItemTreeView.TreeRow.prototype.getField = function(field, unformatted)
return this.ref.getField(field, unformatted, true);
}
Zotero.ItemTreeView.TreeRow.prototype.numChildren = function()
Zotero.ItemTreeView.TreeRow.prototype.numChildren = function(includeTrashed)
{
if(this.ref.isRegularItem())
return this.ref.numChildren();
return this.ref.numChildren(includeTrashed);
else
return 0;
}
Zotero.ItemTreeView.TreeRow.prototype.numNotes = function()
Zotero.ItemTreeView.TreeRow.prototype.numNotes = function(includeTrashed)
{
if(this.ref.isRegularItem())
return this.ref.numNotes();
return this.ref.numNotes(includeTrashed);
else
return 0;
}
Zotero.ItemTreeView.TreeRow.prototype.numAttachments = function()
Zotero.ItemTreeView.TreeRow.prototype.numAttachments = function(includeTrashed)
{
if(this.ref.isRegularItem())
return this.ref.numAttachments();
return this.ref.numAttachments(includeTrashed);
else
return 0;
}