diff --git a/chrome/content/zotero/overlay.js b/chrome/content/zotero/overlay.js index 5d00bb7c4..3a9ff4eb2 100644 --- a/chrome/content/zotero/overlay.js +++ b/chrome/content/zotero/overlay.js @@ -47,6 +47,7 @@ var ZoteroPane = new function() this.updateTagFilter = updateTagFilter; this.onCollectionSelected = onCollectionSelected; this.itemSelected = itemSelected; + this.duplicateSelectedItem = duplicateSelectedItem; this.deleteSelectedItem = deleteSelectedItem; this.deleteSelectedCollection = deleteSelectedCollection; this.editSelectedCollection = editSelectedCollection; @@ -717,6 +718,17 @@ var ZoteroPane = new function() } + function duplicateSelectedItem() { + var newItemID = this.getSelectedItems()[0].clone(); + var newItem = Zotero.Items.get(newItemID); + + if (this.itemsView._itemGroup.isCollection()) { + this.itemsView._itemGroup.ref.addItem(newItem.getID()); + this.selectItem(newItemID); + } + } + + /* * _force_ deletes item from DB even if removing from a collection or search */ @@ -1092,12 +1104,13 @@ var ZoteroPane = new function() attachSnapshot: 3, attachLink: 4, sep2: 5, - deleteItem: 6, - deleteFromLibrary: 7, - sep3: 8, - exportItems: 9, - createBib: 10, - loadReport: 11 + duplicateItem: 6, + deleteItem: 7, + deleteFromLibrary: 8, + sep3: 9, + exportItems: 10, + createBib: 11, + loadReport: 12 }; var menu = document.getElementById('zotero-itemmenu'); @@ -1105,14 +1118,15 @@ var ZoteroPane = new function() var enable = [], disable = [], show = [], hide = [], multiple = ''; if (this.itemsView && this.itemsView.selection.count > 0) { - enable.push(m.showInLibrary, m.addNote, m.attachSnapshot, m.attachLink, m.sep2, - m.deleteItem, m.deleteFromLibrary, m.exportItems, m.createBib, m.loadReport); + enable.push(m.showInLibrary, m.addNote, m.attachSnapshot, m.attachLink, + m.sep2, m.duplicateItem, m.deleteItem, m.deleteFromLibrary, + m.exportItems, m.createBib, m.loadReport); // Multiple items selected if (this.itemsView.selection.count > 1) { var multiple = '.multiple'; hide.push(m.showInLibrary, m.sep1, m.addNote, m.attachSnapshot, - m.attachLink, m.sep2); + m.attachLink, m.sep2, m.duplicateItem); } // Single item selected else @@ -1137,6 +1151,13 @@ var ZoteroPane = new function() { hide.push(m.addNote, m.attachSnapshot, m.attachLink, m.sep2); } + + if (item.isAttachment()) { + hide.push(m.duplicateItem); + } + else { + show.push(m.duplicateItem); + } } } else @@ -1149,8 +1170,8 @@ var ZoteroPane = new function() hide.push(m.showInLibrary, m.sep1); } - disable.push(m.showInLibrary, m.deleteItem, m.deleteFromLibrary, - m.exportItems, m.createBib, m.loadReport); + disable.push(m.showInLibrary, m.duplicateItem, m.deleteItem, + m.deleteFromLibrary, m.exportItems, m.createBib, m.loadReport); hide.push(m.addNote, m.attachSnapshot, m.attachLink, m.sep2); } diff --git a/chrome/content/zotero/overlay.xul b/chrome/content/zotero/overlay.xul index e54b3d0d7..19b0f7c50 100644 --- a/chrome/content/zotero/overlay.xul +++ b/chrome/content/zotero/overlay.xul @@ -90,6 +90,7 @@ + diff --git a/chrome/content/zotero/xpcom/attachments.js b/chrome/content/zotero/xpcom/attachments.js index 076dd5ec7..9069970ba 100644 --- a/chrome/content/zotero/xpcom/attachments.js +++ b/chrome/content/zotero/xpcom/attachments.js @@ -616,14 +616,13 @@ Zotero.Attachments = new function(){ (path ? {string:path} : null) ]; Zotero.DB.query(sql, bindParams); - Zotero.DB.commitTransaction(); if (sourceItemID){ sourceItem.incrementAttachmentCount(); Zotero.Notifier.trigger('modify', 'item', sourceItemID); } - Zotero.Notifier.trigger('add', 'item', attachmentItem.getID()); + Zotero.DB.commitTransaction(); return attachmentItem.getID(); } diff --git a/chrome/content/zotero/xpcom/data_access.js b/chrome/content/zotero/xpcom/data_access.js index 6f74c0f17..e147b3859 100644 --- a/chrome/content/zotero/xpcom/data_access.js +++ b/chrome/content/zotero/xpcom/data_access.js @@ -949,15 +949,11 @@ Zotero.Item.prototype.save = function(){ Zotero.Items.reload(this.getID()); if (isNew){ - if (!Zotero.DB.transactionInProgress()){ - Zotero.Notifier.trigger('add', 'item', this.getID()); - } + Zotero.Notifier.trigger('add', 'item', this.getID()); return this.getID(); } else { - if (!Zotero.DB.transactionInProgress()){ - Zotero.Notifier.trigger('modify', 'item', this.getID(), { old: preItemArray }); - } + Zotero.Notifier.trigger('modify', 'item', this.getID(), { old: preItemArray }); return true; } } @@ -1087,12 +1083,14 @@ Zotero.Item.prototype.setSource = function(sourceItemID){ var newItem = Zotero.Items.get(sourceItemID); // FK check - if (sourceItemID && newItem) { - var preNewItemArray = newItem.toArray(); - } - else { - Zotero.DB.rollbackTransaction(); - throw ("Cannot set " + type + " source to invalid item " + sourceItemID); + if (newItem) { + if (sourceItemID) { + var preNewItemArray = newItem.toArray(); + } + else { + Zotero.DB.rollbackTransaction(); + throw ("Cannot set " + type + " source to invalid item " + sourceItemID); + } } var oldSourceItemID = this.getSource(); @@ -1847,6 +1845,80 @@ Zotero.Item.prototype.getImageSrc = function() { } +Zotero.Item.prototype.clone = function() { + if (!this.getID()) { + throw ('Cannot clone unsaved item in Zotero.Item.clone()'); + } + + if (this.isAttachment()) { + throw ('Cloning attachment items not supported in Zotero.Item.clone()'); + } + + Zotero.DB.beginTransaction(); + + var obj = this.toArray(); + + // Note + if (this.isNote()) { + var newItemID = Zotero.Notes.add(this.getNote(), this.getSource()); + var newItem = Zotero.Items.get(newItemID); + } + + // Regular item + else { + var itemTypeID = this.getType(); + var newItem = new Zotero.Item(itemTypeID); + + for (var i in obj) { + switch (i) { + // TODO: remove when title is changed to regular field + case 'title': + if (obj.itemType != 'note') { + newItem.setField('title', obj[i]); + } + continue; + + // toArray()'s 'abstractNote' is 'abstract' field + case 'abstractNote': + newItem.setField('abstract', obj[i]); + continue; + + case 'creators': + var i = 0; + for each(var c in obj.creators) { + newItem.setCreator(i, c.firstName, c.lastName, + c.creatorType, c.fieldMode ? c.fieldMode : null); + i++; + } + continue; + } + + var fieldID = Zotero.ItemFields.getID(i); + if (fieldID && Zotero.ItemFields.isValidForType(fieldID, itemTypeID)) { + newItem.setField(i, obj[i]); + } + } + + newItem.save(); + } + + if (obj.tags) { + for each(var tag in obj.tags) { + newItem.addTagByID(tag.id); + } + } + + if (obj.seeAlso) { + for each(var id in obj.seeAlso) { + newItem.addSeeAlso(id) + } + } + + Zotero.DB.commitTransaction(); + return newItem.getID(); +} + + /** * Delete item from database and clear from Zotero.Items internal array **/ diff --git a/chrome/locale/en-US/zotero/zotero.dtd b/chrome/locale/en-US/zotero/zotero.dtd index 7a08ac938..e54eef0b4 100644 --- a/chrome/locale/en-US/zotero/zotero.dtd +++ b/chrome/locale/en-US/zotero/zotero.dtd @@ -25,6 +25,7 @@ +