Copy annotations across libraries
Based on option in prefs When copying an annotation group the
This commit is contained in:
parent
67451dffd5
commit
f684984b07
7 changed files with 99 additions and 16 deletions
|
@ -1540,7 +1540,8 @@ var CollectionTree = class CollectionTree extends LibraryTree {
|
||||||
tags: Zotero.Prefs.get('groups.copyTags'),
|
tags: Zotero.Prefs.get('groups.copyTags'),
|
||||||
childNotes: Zotero.Prefs.get('groups.copyChildNotes'),
|
childNotes: Zotero.Prefs.get('groups.copyChildNotes'),
|
||||||
childLinks: Zotero.Prefs.get('groups.copyChildLinks'),
|
childLinks: Zotero.Prefs.get('groups.copyChildLinks'),
|
||||||
childFileAttachments: Zotero.Prefs.get('groups.copyChildFileAttachments')
|
childFileAttachments: Zotero.Prefs.get('groups.copyChildFileAttachments'),
|
||||||
|
annotations: Zotero.Prefs.get('groups.copyAnnotations'),
|
||||||
};
|
};
|
||||||
var copyItem = async function (item, targetLibraryID, options) {
|
var copyItem = async function (item, targetLibraryID, options) {
|
||||||
var targetLibraryType = Zotero.Libraries.get(targetLibraryID).libraryType;
|
var targetLibraryType = Zotero.Libraries.get(targetLibraryID).libraryType;
|
||||||
|
@ -1612,7 +1613,12 @@ var CollectionTree = class CollectionTree extends LibraryTree {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Zotero.Attachments.copyAttachmentToLibrary(item, targetLibraryID);
|
let newAttachment = Zotero.Attachments.copyAttachmentToLibrary(item, targetLibraryID);
|
||||||
|
if (options.annotations) {
|
||||||
|
await Zotero.Items.copyChildItems(item, newAttachment);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newAttachment.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create new clone item in target library
|
// Create new clone item in target library
|
||||||
|
@ -1675,7 +1681,13 @@ var CollectionTree = class CollectionTree extends LibraryTree {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await Zotero.Attachments.copyAttachmentToLibrary(attachment, targetLibraryID, newItemID);
|
let newAttachment = await Zotero.Attachments.copyAttachmentToLibrary(
|
||||||
|
attachment, targetLibraryID, newItemID
|
||||||
|
);
|
||||||
|
|
||||||
|
if (options.annotations) {
|
||||||
|
await Zotero.Items.copyChildItems(attachment, newAttachment);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1804,6 +1816,7 @@ var CollectionTree = class CollectionTree extends LibraryTree {
|
||||||
copyOptions.childNotes = io.includeNotes;
|
copyOptions.childNotes = io.includeNotes;
|
||||||
copyOptions.childFileAttachments = io.includeFiles;
|
copyOptions.childFileAttachments = io.includeFiles;
|
||||||
copyOptions.childLinks = true;
|
copyOptions.childLinks = true;
|
||||||
|
copyOptions.annotations = false;
|
||||||
['keepRights', 'license', 'licenseName'].forEach(function (field) {
|
['keepRights', 'license', 'licenseName'].forEach(function (field) {
|
||||||
copyOptions[field] = io[field];
|
copyOptions[field] = io[field];
|
||||||
});
|
});
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
|
|
||||||
<preference id="pref-groups-copyChildNotes" name="extensions.zotero.groups.copyChildNotes" type="bool"/>
|
<preference id="pref-groups-copyChildNotes" name="extensions.zotero.groups.copyChildNotes" type="bool"/>
|
||||||
<preference id="pref-groups-copyChildFileAttachments" name="extensions.zotero.groups.copyChildFileAttachments" type="bool"/>
|
<preference id="pref-groups-copyChildFileAttachments" name="extensions.zotero.groups.copyChildFileAttachments" type="bool"/>
|
||||||
|
<preference id="pref-groups-copyAnnotations" name="extensions.zotero.groups.copyAnnotations" type="bool"/>
|
||||||
<preference id="pref-groups-copyChildLinks" name="extensions.zotero.groups.copyChildLinks" type="bool"/>
|
<preference id="pref-groups-copyChildLinks" name="extensions.zotero.groups.copyChildLinks" type="bool"/>
|
||||||
<preference id="pref-groups-copyTags" name="extensions.zotero.groups.copyTags" type="bool"/>
|
<preference id="pref-groups-copyTags" name="extensions.zotero.groups.copyTags" type="bool"/>
|
||||||
</preferences>
|
</preferences>
|
||||||
|
@ -96,6 +97,7 @@
|
||||||
<vbox style="margin-left: 2em">
|
<vbox style="margin-left: 2em">
|
||||||
<checkbox label="&zotero.preferences.groups.childNotes;" preference="pref-groups-copyChildNotes"/>
|
<checkbox label="&zotero.preferences.groups.childNotes;" preference="pref-groups-copyChildNotes"/>
|
||||||
<checkbox label="&zotero.preferences.groups.childFiles;" preference="pref-groups-copyChildFileAttachments"/>
|
<checkbox label="&zotero.preferences.groups.childFiles;" preference="pref-groups-copyChildFileAttachments"/>
|
||||||
|
<checkbox label="&zotero.preferences.groups.annotations;" preference="pref-groups-copyAnnotations"/>
|
||||||
<checkbox label="&zotero.preferences.groups.childLinks;" preference="pref-groups-copyChildLinks"/>
|
<checkbox label="&zotero.preferences.groups.childLinks;" preference="pref-groups-copyChildLinks"/>
|
||||||
<checkbox label="&zotero.preferences.groups.tags;" preference="pref-groups-copyTags"/>
|
<checkbox label="&zotero.preferences.groups.tags;" preference="pref-groups-copyTags"/>
|
||||||
</vbox>
|
</vbox>
|
||||||
|
|
|
@ -2682,6 +2682,8 @@ Zotero.Attachments = new function(){
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy attachment item, including file, to another library
|
* Copy attachment item, including file, to another library
|
||||||
|
*
|
||||||
|
* @return {Zotero.Item} - The new attachment
|
||||||
*/
|
*/
|
||||||
this.copyAttachmentToLibrary = Zotero.Promise.coroutine(function* (attachment, libraryID, parentItemID) {
|
this.copyAttachmentToLibrary = Zotero.Promise.coroutine(function* (attachment, libraryID, parentItemID) {
|
||||||
if (attachment.libraryID == libraryID) {
|
if (attachment.libraryID == libraryID) {
|
||||||
|
@ -2708,7 +2710,7 @@ Zotero.Attachments = new function(){
|
||||||
}
|
}
|
||||||
|
|
||||||
yield newAttachment.addLinkedItem(attachment);
|
yield newAttachment.addLinkedItem(attachment);
|
||||||
return newAttachment.id;
|
return newAttachment;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -882,6 +882,36 @@ Zotero.Items = function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy child items from one item to another (e.g., in another library)
|
||||||
|
*
|
||||||
|
* Requires a transaction
|
||||||
|
*/
|
||||||
|
this.copyChildItems = async function (fromItem, toItem) {
|
||||||
|
Zotero.DB.requireTransaction();
|
||||||
|
|
||||||
|
var fromGroup = fromItem.library.isGroup;
|
||||||
|
|
||||||
|
// Annotations on files
|
||||||
|
if (fromItem.isFileAttachment()) {
|
||||||
|
let annotations = fromItem.getAnnotations();
|
||||||
|
for (let annotation of annotations) {
|
||||||
|
let newAnnotation = annotation.clone(toItem.libraryID);
|
||||||
|
newAnnotation.parentItemID = toItem.id;
|
||||||
|
// If there's no explicit author and we're copying from a group, set the author
|
||||||
|
// to the creating user
|
||||||
|
if (!annotation.annotationAuthorName && fromGroup) {
|
||||||
|
newAnnotation.annotationAuthorName =
|
||||||
|
Zotero.Users.getName(annotation.createdByUserID);
|
||||||
|
}
|
||||||
|
await newAnnotation.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Other things as necessary
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move child items from one item to another
|
* Move child items from one item to another
|
||||||
*
|
*
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
<!ENTITY zotero.preferences.groups.whenCopyingInclude "When copying items between libraries, include:">
|
<!ENTITY zotero.preferences.groups.whenCopyingInclude "When copying items between libraries, include:">
|
||||||
<!ENTITY zotero.preferences.groups.childNotes "child notes">
|
<!ENTITY zotero.preferences.groups.childNotes "child notes">
|
||||||
<!ENTITY zotero.preferences.groups.childFiles "child snapshots and imported files">
|
<!ENTITY zotero.preferences.groups.childFiles "child snapshots and imported files">
|
||||||
|
<!ENTITY zotero.preferences.groups.annotations "annotations">
|
||||||
<!ENTITY zotero.preferences.groups.childLinks "child links">
|
<!ENTITY zotero.preferences.groups.childLinks "child links">
|
||||||
<!ENTITY zotero.preferences.groups.tags "tags">
|
<!ENTITY zotero.preferences.groups.tags "tags">
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,7 @@ pref("extensions.zotero.reopenPanesOnRestart", true);
|
||||||
|
|
||||||
pref("extensions.zotero.groups.copyChildLinks", true);
|
pref("extensions.zotero.groups.copyChildLinks", true);
|
||||||
pref("extensions.zotero.groups.copyChildFileAttachments", true);
|
pref("extensions.zotero.groups.copyChildFileAttachments", true);
|
||||||
|
pref("extensions.zotero.groups.copyAnnotations", true);
|
||||||
pref("extensions.zotero.groups.copyChildNotes", true);
|
pref("extensions.zotero.groups.copyChildNotes", true);
|
||||||
pref("extensions.zotero.groups.copyTags", true);
|
pref("extensions.zotero.groups.copyTags", true);
|
||||||
|
|
||||||
|
|
|
@ -814,21 +814,22 @@ describe("Zotero.CollectionTree", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should copy an item with an attachment to a group", function* () {
|
it("should copy an item with a PDF attachment containing annotations to a group", async function () {
|
||||||
var group = yield createGroup();
|
var group = await createGroup();
|
||||||
|
|
||||||
var item = yield createDataObject('item', false, { skipSelect: true });
|
var item = await createDataObject('item', false, { skipSelect: true });
|
||||||
var file = getTestDataDirectory();
|
var file = getTestDataDirectory();
|
||||||
file.append('test.png');
|
file.append('test.pdf');
|
||||||
var attachment = yield Zotero.Attachments.importFromFile({
|
var attachment = await Zotero.Attachments.importFromFile({
|
||||||
file: file,
|
file,
|
||||||
parentItemID: item.id
|
parentItemID: item.id
|
||||||
});
|
});
|
||||||
|
var annotation = await createAnnotation('highlight', attachment);
|
||||||
|
|
||||||
var ids = (yield onDrop('item', 'L' + group.libraryID, [item.id])).ids;
|
var ids = (await onDrop('item', 'L' + group.libraryID, [item.id])).ids;
|
||||||
|
|
||||||
yield cv.selectLibrary(group.libraryID);
|
await cv.selectLibrary(group.libraryID);
|
||||||
yield waitForItemsLoad(win);
|
await waitForItemsLoad(win);
|
||||||
|
|
||||||
// Check parent
|
// Check parent
|
||||||
var itemsView = win.ZoteroPane.itemsView;
|
var itemsView = win.ZoteroPane.itemsView;
|
||||||
|
@ -837,7 +838,7 @@ describe("Zotero.CollectionTree", function() {
|
||||||
assert.equal(treeRow.ref.libraryID, group.libraryID);
|
assert.equal(treeRow.ref.libraryID, group.libraryID);
|
||||||
assert.equal(treeRow.ref.id, ids[0]);
|
assert.equal(treeRow.ref.id, ids[0]);
|
||||||
// New item should link back to original
|
// New item should link back to original
|
||||||
var linked = yield item.getLinkedItem(group.libraryID);
|
var linked = await item.getLinkedItem(group.libraryID);
|
||||||
assert.equal(linked.id, treeRow.ref.id);
|
assert.equal(linked.id, treeRow.ref.id);
|
||||||
|
|
||||||
// Check attachment
|
// Check attachment
|
||||||
|
@ -847,11 +848,44 @@ describe("Zotero.CollectionTree", function() {
|
||||||
treeRow = itemsView.getRow(1);
|
treeRow = itemsView.getRow(1);
|
||||||
assert.equal(treeRow.ref.id, ids[1]);
|
assert.equal(treeRow.ref.id, ids[1]);
|
||||||
// New attachment should link back to original
|
// New attachment should link back to original
|
||||||
linked = yield attachment.getLinkedItem(group.libraryID);
|
linked = await attachment.getLinkedItem(group.libraryID);
|
||||||
assert.equal(linked.id, treeRow.ref.id);
|
assert.equal(linked.id, treeRow.ref.id);
|
||||||
|
|
||||||
|
// Check annotation
|
||||||
|
var groupAttachment = Zotero.Items.get(treeRow.ref.id);
|
||||||
|
var annotations = groupAttachment.getAnnotations();
|
||||||
|
assert.lengthOf(annotations, 1);
|
||||||
|
|
||||||
return group.eraseTx();
|
return group.eraseTx();
|
||||||
})
|
});
|
||||||
|
|
||||||
|
it("should copy a group item with a PDF attachment containing annotations to the personal library", async function () {
|
||||||
|
var group = await createGroup();
|
||||||
|
await cv.selectLibrary(group.libraryID);
|
||||||
|
|
||||||
|
var groupItem = await createDataObject('item', { libraryID: group.libraryID });
|
||||||
|
var file = getTestDataDirectory();
|
||||||
|
file.append('test.pdf');
|
||||||
|
var attachment = await Zotero.Attachments.importFromFile({
|
||||||
|
file,
|
||||||
|
parentItemID: groupItem.id
|
||||||
|
});
|
||||||
|
var annotation = await createAnnotation('highlight', attachment);
|
||||||
|
await Zotero.Users.setName(12345, 'Name');
|
||||||
|
annotation.createdByUserID = 12345;
|
||||||
|
|
||||||
|
var ids = (await onDrop('item', 'L1', [groupItem.id])).ids;
|
||||||
|
var newItem = Zotero.Items.get(ids[0]);
|
||||||
|
|
||||||
|
var newAttachment = Zotero.Items.get(newItem.getAttachments())[0];
|
||||||
|
|
||||||
|
// Check annotation
|
||||||
|
var annotations = newAttachment.getAnnotations();
|
||||||
|
assert.lengthOf(annotations, 1);
|
||||||
|
assert.equal(annotations[0].annotationAuthorName, 'Name');
|
||||||
|
|
||||||
|
return group.eraseTx();
|
||||||
|
});
|
||||||
|
|
||||||
it("should not copy an item or its attachment to a group twice", function* () {
|
it("should not copy an item or its attachment to a group twice", function* () {
|
||||||
var group = yield getGroup();
|
var group = yield getGroup();
|
||||||
|
|
Loading…
Reference in a new issue