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 @@
+