mirror of
https://github.com/zotero/zotero.git
synced 2026-10-11 03:38:25 +00:00
Compare commits
251 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
47610d0faa | ||
|
|
42e042c6c6 | ||
|
|
b9a5fd9f78 | ||
|
|
cbb524d257 | ||
|
|
93ea818bf2 | ||
|
|
d2243cc339 | ||
|
|
f06267e4cd | ||
|
|
624101832e | ||
|
|
6bc1551f7f | ||
|
|
a8a0cabcc4 | ||
|
|
9d80c54d5d | ||
|
|
1c8554d527 | ||
|
|
5cea183ae3 | ||
|
|
92434dbb78 | ||
|
|
2c5a91682e | ||
|
|
3cc54eaf95 | ||
|
|
7f91a0c1a8 | ||
|
|
77fdc8e40c | ||
|
|
c5a769285b | ||
|
|
fe09afa0a6 | ||
|
|
ab2bec936e | ||
|
|
af66712c77 | ||
|
|
7db16843b3 | ||
|
|
a4eafd0307 | ||
|
|
4e1754b960 | ||
|
|
238c7ce410 | ||
|
|
8a15e5abe0 | ||
|
|
159c112257 | ||
|
|
70f9462913 | ||
|
|
4b5e2eae1b | ||
|
|
c4876fd5ae | ||
|
|
7fcc1d35a4 | ||
|
|
d0d3ed731d | ||
|
|
f2bfaeb7a9 | ||
|
|
2fa67bae64 | ||
|
|
a2db01c633 | ||
|
|
2b9e9c174f | ||
|
|
aa0ef7012c | ||
|
|
73306ee5fb | ||
|
|
d8d6054927 | ||
|
|
410ebc288b | ||
|
|
55095ba354 | ||
|
|
3ba6343668 | ||
|
|
d37aa37629 | ||
|
|
3582405f55 | ||
|
|
78eb857e73 | ||
|
|
618e71b5f1 | ||
|
|
7bada8ce0c | ||
|
|
af436d34a8 | ||
|
|
e45becce2a | ||
|
|
fb4f7b7932 | ||
|
|
fd8aa4433c | ||
|
|
29dd0cf5dc | ||
|
|
28329aa785 | ||
|
|
c5d418fc16 | ||
|
|
e9c6c76e79 | ||
|
|
f13966894f | ||
|
|
b7cc1d549b | ||
|
|
9a3f8dbc94 | ||
|
|
b594ad0b0a | ||
|
|
4dd1851140 | ||
|
|
006dd20d5b | ||
|
|
55afe7c08d | ||
|
|
9fadfac7ee | ||
|
|
38ae3a2600 | ||
|
|
473dd2ed64 | ||
|
|
e3b1cbd4eb | ||
|
|
3b93147052 | ||
|
|
b9a1e93518 | ||
|
|
99084084d4 | ||
|
|
64047f181a | ||
|
|
12b1897478 | ||
|
|
8fc9ebe4ab | ||
|
|
5162845179 | ||
|
|
2569ad6506 | ||
|
|
4fdf43ed92 | ||
|
|
9691fcafc2 | ||
|
|
6aad0cbb9c | ||
|
|
a7e6fc330c | ||
|
|
677499865a | ||
|
|
0e60389ee4 | ||
|
|
2271913e49 | ||
|
|
ff5e09201d | ||
|
|
0b89b15f66 | ||
|
|
f6e11981e3 | ||
|
|
230fc7f2df | ||
|
|
f179f0a54f | ||
|
|
ea09aac616 | ||
|
|
4a49ffec0a | ||
|
|
0d09618865 | ||
|
|
b96fcd41b1 | ||
|
|
c13d17b5e6 | ||
|
|
eb255c5868 | ||
|
|
88217492f9 | ||
|
|
64897455f4 | ||
|
|
5015b0e4cc | ||
|
|
a2d378448a | ||
|
|
32b64b3cf1 | ||
|
|
66fccec6b4 | ||
|
|
894309d061 | ||
|
|
b24c7577ec | ||
|
|
ca4ced1e9f | ||
|
|
6646be66d0 | ||
|
|
ef0811bd4c | ||
|
|
f893206dfd | ||
|
|
ae5de2c2f5 | ||
|
|
a3b45a74e9 | ||
|
|
e474ca524b | ||
|
|
bc0f6203e1 | ||
|
|
91ae576074 | ||
|
|
c255104ada | ||
|
|
75f5d6aca1 | ||
|
|
d156bef42a | ||
|
|
79246196ac | ||
|
|
262e1964ae | ||
|
|
f4dfea6849 | ||
|
|
999f78b0f5 | ||
|
|
2e6321a4bf | ||
|
|
35a1bb20cb | ||
|
|
8c80ea431e | ||
|
|
3abd720957 | ||
|
|
8379540719 | ||
|
|
b373291c02 | ||
|
|
3391f3bc99 | ||
|
|
6ca854a018 | ||
|
|
fa32eb6790 | ||
|
|
96c4427d6c | ||
|
|
5a8b5a1829 | ||
|
|
f368a53311 | ||
|
|
49020b02a2 | ||
|
|
20c6fe6737 | ||
|
|
80351a496b | ||
|
|
2d2e787111 | ||
|
|
eaba3ae099 | ||
|
|
4746300d33 | ||
|
|
85b0c9dbad | ||
|
|
318e4852e9 | ||
|
|
3dc3359cff | ||
|
|
b505c630d3 | ||
|
|
21b7baee35 | ||
|
|
df59cee94a | ||
|
|
d1275f9964 | ||
|
|
d4a7de2e8d | ||
|
|
864fd03c87 | ||
|
|
d3cb7c86d9 | ||
|
|
e4e3c72036 | ||
|
|
0857cefb0c | ||
|
|
9b7b4fe134 | ||
|
|
a9c3fc7790 | ||
|
|
20d0f103fd | ||
|
|
20eca3781d | ||
|
|
87455d28c3 | ||
|
|
2048319541 | ||
|
|
d03b0a716d | ||
|
|
bb2b37a73a | ||
|
|
7ec54fdaa9 | ||
|
|
5a659b070d | ||
|
|
ad96323881 | ||
|
|
fc0f6157d0 | ||
|
|
6733f2edca | ||
|
|
e1997620a4 | ||
|
|
a396771cbc | ||
|
|
0e0997078b | ||
|
|
0785b3a086 | ||
|
|
ba5cb7d5c6 | ||
|
|
d822da4c06 | ||
|
|
a297692487 | ||
|
|
6921268dc0 | ||
|
|
ba1906c054 | ||
|
|
b5be7cbd57 | ||
|
|
5c61815f36 | ||
|
|
b5ca5aed3a | ||
|
|
4b6598acc4 | ||
|
|
14a6ce000e | ||
|
|
9d0cd005f8 | ||
|
|
26db75971e | ||
|
|
cc45e9019b | ||
|
|
98d6f40e4a | ||
|
|
2cad5b00d1 | ||
|
|
95239db0fd | ||
|
|
4c063e7b6e | ||
|
|
07f1517712 | ||
|
|
f0e0971c69 | ||
|
|
acba90f272 | ||
|
|
26a5e2900a | ||
|
|
34d66381d1 | ||
|
|
f7dbcdde4b | ||
|
|
c4563af381 | ||
|
|
56e7f0a10f | ||
|
|
3a160b2630 | ||
|
|
124c18d54d | ||
|
|
57c582e171 | ||
|
|
cf8819cc06 | ||
|
|
fe74b02d28 | ||
|
|
1dcc2728dd | ||
|
|
c5dbf0169f | ||
|
|
3f282fc25f | ||
|
|
7163a196f8 | ||
|
|
8c0499468e | ||
|
|
629892b0b8 | ||
|
|
2ff67c987e | ||
|
|
a8ed30ce80 | ||
|
|
43f15e7517 | ||
|
|
df11227e0a | ||
|
|
d418d79e70 | ||
|
|
42aebccbf4 | ||
|
|
7b6e19435b | ||
|
|
f650f95081 | ||
|
|
0357026865 | ||
|
|
92d89becc7 | ||
|
|
49f9642c0d | ||
|
|
94372111f5 | ||
|
|
f0b896d282 | ||
|
|
ec68216310 | ||
|
|
b215d93ac9 | ||
|
|
bf1480f8f0 | ||
|
|
6f089445a5 | ||
|
|
14e62ee34f | ||
|
|
43c86c0e58 | ||
|
|
6f3f5d2ea8 | ||
|
|
4fb0661b50 | ||
|
|
57ab92b5b9 | ||
|
|
7b20972c27 | ||
|
|
dc045250a6 | ||
|
|
256bd157ed | ||
|
|
2b45b7fea3 | ||
|
|
1d5fd1308a | ||
|
|
d8069fac50 | ||
|
|
18516a33d9 | ||
|
|
b658f09dd8 | ||
|
|
5799bdd554 | ||
|
|
62c7b4db2b | ||
|
|
caa0b05e5f | ||
|
|
5095543bef | ||
|
|
6af3b0276a | ||
|
|
67700f8a2c | ||
|
|
d12f3eda61 | ||
|
|
deabf3f042 | ||
|
|
28ed3e34b5 | ||
|
|
354183c25d | ||
|
|
b0f69ef7e3 | ||
|
|
ebc23d73b0 | ||
|
|
419f74379b | ||
|
|
603b843f71 | ||
|
|
1e3959020d | ||
|
|
3fd0abf6b0 | ||
|
|
111a254696 | ||
|
|
69616500d8 | ||
|
|
693f9a7e1b | ||
|
|
0c0afb129b | ||
|
|
a11c5987ad |
308 changed files with 12618 additions and 5383 deletions
|
|
@ -7,8 +7,9 @@ content zotero-platform chrome/content/zotero-platform/unix/ os=FreeBSD
|
||||||
content zotero-platform chrome/content/zotero-platform/unix/ os=OpenBSD
|
content zotero-platform chrome/content/zotero-platform/unix/ os=OpenBSD
|
||||||
|
|
||||||
content zotero-platform-version chrome/content/zotero-platform/default-version/
|
content zotero-platform-version chrome/content/zotero-platform/default-version/
|
||||||
# Big Sur shows up as 10.16 when linked against 10.11
|
# Big Sur and later show up as 10.16 when linked against 10.11
|
||||||
content zotero-platform-version chrome/content/zotero-platform/mac-big-sur/ os=Darwin osversion=10.16
|
# (Usually: https://forums.zotero.org/discussion/98406/zotero-will-not-open-mac-os-monterey)
|
||||||
|
content zotero-platform-version chrome/content/zotero-platform/mac-big-sur/ os=Darwin osversion>=10.16
|
||||||
#content zotero-platform-version chrome/content/zotero-platform/mac-big-sur/ os=Darwin
|
#content zotero-platform-version chrome/content/zotero-platform/mac-big-sur/ os=Darwin
|
||||||
|
|
||||||
resource zotero resource/
|
resource zotero resource/
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ var Scaffold = new function () {
|
||||||
var _translatorsLoadedPromise;
|
var _translatorsLoadedPromise;
|
||||||
var _translatorProvider = null;
|
var _translatorProvider = null;
|
||||||
var _lastModifiedTime = 0;
|
var _lastModifiedTime = 0;
|
||||||
|
var _needRebuildTranslatorSuggestions = true;
|
||||||
|
|
||||||
var _editors = {};
|
var _editors = {};
|
||||||
|
|
||||||
|
|
@ -99,15 +100,6 @@ var Scaffold = new function () {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set font size from general pref
|
|
||||||
Zotero.setFontSize(document.getElementById('scaffold-pane'));
|
|
||||||
|
|
||||||
// Set font size of code editor
|
|
||||||
var size = Zotero.Prefs.get("scaffold.fontSize");
|
|
||||||
if (size) {
|
|
||||||
this.setFontSize(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.generateTranslatorID();
|
this.generateTranslatorID();
|
||||||
|
|
||||||
// Add List fields help menu entries for all other item types
|
// Add List fields help menu entries for all other item types
|
||||||
|
|
@ -146,6 +138,15 @@ var Scaffold = new function () {
|
||||||
this.initCodeEditor();
|
this.initCodeEditor();
|
||||||
this.initTestsEditor();
|
this.initTestsEditor();
|
||||||
|
|
||||||
|
// Set font size from general pref
|
||||||
|
Zotero.setFontSize(document.getElementById('scaffold-pane'));
|
||||||
|
|
||||||
|
// Set font size of code editor
|
||||||
|
var size = Zotero.Prefs.get("scaffold.fontSize");
|
||||||
|
if (size) {
|
||||||
|
this.setFontSize(size);
|
||||||
|
}
|
||||||
|
|
||||||
// Listen for Scaffold coming to the foreground and reload translators
|
// Listen for Scaffold coming to the foreground and reload translators
|
||||||
window.addEventListener('activate', () => this.reloadTranslators());
|
window.addEventListener('activate', () => this.reloadTranslators());
|
||||||
|
|
||||||
|
|
@ -156,6 +157,7 @@ var Scaffold = new function () {
|
||||||
|
|
||||||
onLoadComplete: () => {
|
onLoadComplete: () => {
|
||||||
document.getElementById('cmd_load').removeAttribute('disabled');
|
document.getElementById('cmd_load').removeAttribute('disabled');
|
||||||
|
_needRebuildTranslatorSuggestions = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -267,6 +269,7 @@ var Scaffold = new function () {
|
||||||
|
|
||||||
monaco.languages.registerCodeLensProvider('javascript', this.createRunCodeLensProvider(monaco, editor));
|
monaco.languages.registerCodeLensProvider('javascript', this.createRunCodeLensProvider(monaco, editor));
|
||||||
monaco.languages.registerHoverProvider('javascript', this.createHoverProvider(monaco, editor));
|
monaco.languages.registerHoverProvider('javascript', this.createHoverProvider(monaco, editor));
|
||||||
|
monaco.languages.registerCompletionItemProvider('javascript', this.createCompletionProvider(monaco, editor));
|
||||||
|
|
||||||
let tsLib = await Zotero.File.getContentsAsync(
|
let tsLib = await Zotero.File.getContentsAsync(
|
||||||
OS.Path.join(Scaffold_Translators.getDirectory(), 'index.d.ts'));
|
OS.Path.join(Scaffold_Translators.getDirectory(), 'index.d.ts'));
|
||||||
|
|
@ -501,6 +504,43 @@ var Scaffold = new function () {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.createCompletionProvider = function (monaco, editor) {
|
||||||
|
let suggestions = null;
|
||||||
|
return {
|
||||||
|
provideCompletionItems(model, position) {
|
||||||
|
let prefixText = model.getValueInRange({
|
||||||
|
startLineNumber: position.lineNumber,
|
||||||
|
startColumn: 1,
|
||||||
|
endLineNumber: position.lineNumber,
|
||||||
|
endColumn: position.column
|
||||||
|
});
|
||||||
|
if (/setTranslator\([^)]*$/.test(prefixText)) {
|
||||||
|
let word = model.getWordUntilPosition(position);
|
||||||
|
let range = {
|
||||||
|
startLineNumber: position.lineNumber,
|
||||||
|
endLineNumber: position.lineNumber,
|
||||||
|
startColumn: word.startColumn,
|
||||||
|
endColumn: word.endColumn
|
||||||
|
};
|
||||||
|
if (!suggestions || _needRebuildTranslatorSuggestions) {
|
||||||
|
// Cache the suggestions minus the range field
|
||||||
|
suggestions = [...Scaffold_Translators._translators.entries()].map(([id, meta]) => {
|
||||||
|
return {
|
||||||
|
label: `${meta.translator.label}: '${id}'`,
|
||||||
|
kind: monaco.languages.CompletionItemKind.Constant,
|
||||||
|
insertText: `'${id}'`
|
||||||
|
};
|
||||||
|
});
|
||||||
|
_needRebuildTranslatorSuggestions = false;
|
||||||
|
}
|
||||||
|
// Add the range to each suggestion before returning
|
||||||
|
return { suggestions: suggestions.map(s => ({ ...s, range })) };
|
||||||
|
}
|
||||||
|
return { suggestions: [] };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
this.updateModelMarkers = function (translatorPath) {
|
this.updateModelMarkers = function (translatorPath) {
|
||||||
runESLint(translatorPath)
|
runESLint(translatorPath)
|
||||||
.then(eslintOutputToModelMarkers)
|
.then(eslintOutputToModelMarkers)
|
||||||
|
|
@ -1729,6 +1769,9 @@ var Scaffold = new function () {
|
||||||
var url = item.getElementsByTagName("listcell")[0].getAttribute("label");
|
var url = item.getElementsByTagName("listcell")[0].getAttribute("label");
|
||||||
var test = JSON.parse(item.getUserData("test-string"));
|
var test = JSON.parse(item.getUserData("test-string"));
|
||||||
var urlOrData = (test.input !== undefined) ? test.input : url;
|
var urlOrData = (test.input !== undefined) ? test.input : url;
|
||||||
|
if (typeof urlOrData !== 'string') {
|
||||||
|
urlOrData = JSON.stringify(urlOrData, null, '\t');
|
||||||
|
}
|
||||||
Zotero.Utilities.Internal.copyTextToClipboard(urlOrData);
|
Zotero.Utilities.Internal.copyTextToClipboard(urlOrData);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
async function detectWeb(doc, url) {
|
function detectWeb(doc, url) {
|
||||||
// TODO: adjust the logic here
|
// TODO: adjust the logic here
|
||||||
if ($$CURSOR$$url.includes('/article/')) {
|
if ($$CURSOR$$url.includes('/article/')) {
|
||||||
return 'newspaperArticle';
|
return 'newspaperArticle';
|
||||||
|
|
@ -52,12 +52,12 @@ function getSearchResults(doc, checkOnly) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function doWeb(doc, url) {
|
async function doWeb(doc, url) {
|
||||||
if (await detectWeb(doc, url) == 'multiple') {
|
if (detectWeb(doc, url) == 'multiple') {
|
||||||
let items = await Zotero.selectItems(getSearchResults(doc, false));
|
let items = await Zotero.selectItems(getSearchResults(doc, false));
|
||||||
if (items) {
|
if (items) {
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
Object.keys(items)
|
Object.keys(items)
|
||||||
.map(url => requestDocument(url).then(doc => scrape(doc, url)))
|
.map(url => requestDocument(url).then(scrape))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -65,3 +65,8 @@ async function doWeb(doc, url) {
|
||||||
await scrape(doc, url);
|
await scrape(doc, url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function scrape(doc, url = doc.location.href) {
|
||||||
|
// TODO: implement or add a scrape function template
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
async function scrape(doc, url) {
|
async function scrape(doc, url = doc.location.href) {
|
||||||
// TODO adjust the url building
|
// TODO adjust the url building
|
||||||
let m = url.match(/FId=([\w\d]+)&/);
|
let m = url.match(/FId=([\w\d]+)&/);
|
||||||
if (m) {
|
if (m) {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
async function scrape(doc, url) {
|
async function scrape(doc, url = doc.location.href) {
|
||||||
let translator = Zotero.loadTranslator('web');
|
let translator = Zotero.loadTranslator('web');
|
||||||
// Embedded Metadata
|
// Embedded Metadata
|
||||||
translator.setTranslator('951c027d-74ac-47d4-a107-9c3069ab7b48');
|
translator.setTranslator('951c027d-74ac-47d4-a107-9c3069ab7b48');
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
async function scrape(doc, url) {
|
async function scrape(doc, url = doc.location.href) {
|
||||||
// TODO adjust the selector for the lines here
|
// TODO adjust the selector for the lines here
|
||||||
let lines = doc.querySelectorAll('table#marcData tr');
|
let lines = doc.querySelectorAll('table#marcData tr');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
async function scrape(doc, url) {
|
async function scrape(doc, url = doc.location.href) {
|
||||||
let DOI = url.match(/\/(10\.[^#?]+)/)[1];
|
let DOI = url.match(/\/(10\.[^#?]+)/)[1];
|
||||||
// TODO adjust the URL here
|
// TODO adjust the URL here
|
||||||
let risURL = `http://citation-needed.services.springer.com/v2/references/${DOI}?format=refman&flavour=citation`;
|
let risURL = `http://citation-needed.services.springer.com/v2/references/${DOI}?format=refman&flavour=citation`;
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,12 @@ row > label:first-child, .creator-type-label, #more-creators-label
|
||||||
max-height: 7px;
|
max-height: 7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.zotero-focusable:focus {
|
||||||
|
/* At least in Fx60, the color doesn't quite match Monterey's native textbox outline,
|
||||||
|
but it will have to do for now */
|
||||||
|
outline: 2px solid -moz-mac-focusring !important;
|
||||||
|
}
|
||||||
|
|
||||||
textbox
|
textbox
|
||||||
{
|
{
|
||||||
margin: -1px 5px -1px 0;
|
margin: -1px 5px -1px 0;
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,8 @@ input {
|
||||||
|
|
||||||
/* This seems to be necessary to center the tabs. Not sure why. */
|
/* This seems to be necessary to center the tabs. Not sure why. */
|
||||||
.zotero-editpane-tabs > tab:last-of-type > hbox .tab-text {
|
.zotero-editpane-tabs > tab:last-of-type > hbox .tab-text {
|
||||||
margin: 2px 9px 2px 9px !important;
|
margin-left: 9px !important;
|
||||||
|
margin-right: 9px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.zotero-editpane-tabs > tab[selected=true] > hbox .tab-text {
|
.zotero-editpane-tabs > tab[selected=true] > hbox .tab-text {
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,8 @@ var ZoteroAdvancedSearch = new function() {
|
||||||
ref: _searchBox.search,
|
ref: _searchBox.search,
|
||||||
isSearchMode: () => true,
|
isSearchMode: () => true,
|
||||||
getItems: async function () {
|
getItems: async function () {
|
||||||
|
await Zotero.Libraries.get(_libraryID).waitForDataLoad('item');
|
||||||
|
|
||||||
var search = _searchBox.search.clone();
|
var search = _searchBox.search.clone();
|
||||||
search.libraryID = _libraryID;
|
search.libraryID = _libraryID;
|
||||||
var ids = await search.search();
|
var ids = await search.search();
|
||||||
|
|
|
||||||
|
|
@ -719,7 +719,7 @@
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
// getCreatorFields(), switchCreatorMode() and handleCreatorAutoCompleteSelect()
|
// getCreatorFields(), switchCreatorMode() and handleCreatorAutoCompleteSelect()
|
||||||
// may need need to be adjusted if this DOM structure changes
|
// may need need to be adjusted if this DOM structure changes
|
||||||
|
var tabindex = this._tabIndexMinCreators + (this._creatorCount * 6);
|
||||||
var fieldMode = Zotero.Prefs.get('lastCreatorFieldMode');
|
var fieldMode = Zotero.Prefs.get('lastCreatorFieldMode');
|
||||||
var firstName = '';
|
var firstName = '';
|
||||||
var lastName = '';
|
var lastName = '';
|
||||||
|
|
@ -757,9 +757,15 @@
|
||||||
}
|
}
|
||||||
typeBox.setAttribute("fieldname", 'creator-' + this._creatorCount + '-typeID');
|
typeBox.setAttribute("fieldname", 'creator-' + this._creatorCount + '-typeID');
|
||||||
if (this.editable) {
|
if (this.editable) {
|
||||||
typeBox.className = 'creator-type-label zotero-clicky';
|
typeBox.className = 'creator-type-label zotero-clicky zotero-focusable';
|
||||||
|
typeBox.setAttribute('ztabindex', tabindex - 1);
|
||||||
|
typeBox.setAttribute('role', 'listbox');
|
||||||
|
typeBox.addEventListener('focus', ev => {
|
||||||
|
this._lastTabIndex = parseInt(ev.target.getAttribute('ztabindex'));
|
||||||
|
});
|
||||||
var img = document.createElement('image');
|
var img = document.createElement('image');
|
||||||
typeBox.appendChild(img);
|
typeBox.appendChild(img);
|
||||||
|
typeBox.setAttribute('onkeypress', 'return document.getBindingParent(this).handleKeyPress(event)');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
typeBox.className = 'creator-type-label';
|
typeBox.className = 'creator-type-label';
|
||||||
|
|
@ -773,11 +779,17 @@
|
||||||
var hbox = document.createElement("hbox");
|
var hbox = document.createElement("hbox");
|
||||||
hbox.className = 'creator-type-value';
|
hbox.className = 'creator-type-value';
|
||||||
|
|
||||||
|
hbox.addEventListener('focusin', ev => {
|
||||||
|
if(ev.target.classList.contains('zotero-focusable')) {
|
||||||
|
this._lastTabIndex = parseInt(ev.target.getAttribute('ztabindex'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Name
|
// Name
|
||||||
var firstlast = document.createElement("hbox");
|
var firstlast = document.createElement("hbox");
|
||||||
firstlast.className = 'creator-name-box';
|
firstlast.className = 'creator-name-box';
|
||||||
firstlast.setAttribute("flex","1");
|
firstlast.setAttribute("flex","1");
|
||||||
var tabindex = this._tabIndexMinCreators + (this._creatorCount * 2);
|
|
||||||
var fieldName = 'creator-' + this._creatorCount + '-lastName';
|
var fieldName = 'creator-' + this._creatorCount + '-lastName';
|
||||||
var lastNameLabel = firstlast.appendChild(
|
var lastNameLabel = firstlast.appendChild(
|
||||||
this.createValueElement(
|
this.createValueElement(
|
||||||
|
|
@ -820,29 +832,40 @@
|
||||||
var toggleButton = document.createElement('label');
|
var toggleButton = document.createElement('label');
|
||||||
toggleButton.setAttribute('fieldname',
|
toggleButton.setAttribute('fieldname',
|
||||||
'creator-' + this._creatorCount + '-fieldMode');
|
'creator-' + this._creatorCount + '-fieldMode');
|
||||||
toggleButton.className = 'zotero-field-toggle zotero-clicky';
|
toggleButton.setAttribute('ztabindex', tabindex + 2);
|
||||||
|
toggleButton.setAttribute('role', 'button');
|
||||||
|
toggleButton.className = 'zotero-field-toggle zotero-focusable zotero-clicky';
|
||||||
|
toggleButton.setAttribute('onkeypress', 'return document.getBindingParent(this).handleKeyPress(event)');
|
||||||
hbox.appendChild(toggleButton);
|
hbox.appendChild(toggleButton);
|
||||||
|
|
||||||
// Minus (-) button
|
// Minus (-) button
|
||||||
var removeButton = document.createElement('label');
|
var removeButton = document.createElement('label');
|
||||||
|
removeButton.setAttribute('ztabindex', tabindex + 3);
|
||||||
|
removeButton.setAttribute('role', 'button');
|
||||||
|
removeButton.setAttribute('aria-label', Zotero.getString('general.delete'));
|
||||||
removeButton.setAttribute("value","-");
|
removeButton.setAttribute("value","-");
|
||||||
removeButton.setAttribute("class","zotero-clicky zotero-clicky-minus");
|
removeButton.setAttribute('class','zotero-clicky zotero-focusable zotero-clicky-minus');
|
||||||
|
removeButton.setAttribute('onkeypress', 'return document.getBindingParent(this).handleKeyPress(event)');
|
||||||
// If default first row, don't let user remove it
|
// If default first row, don't let user remove it
|
||||||
if (defaultRow) {
|
if (defaultRow) {
|
||||||
this.disableButton(removeButton);
|
this.disableButton(removeButton);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
removeButton.setAttribute("onclick",
|
let index = this._creatorCount;
|
||||||
"document.getBindingParent(this).removeCreator("
|
removeButton.onclick = (ev) => {
|
||||||
+ this._creatorCount
|
document.getBindingParent(ev.currentTarget)
|
||||||
+ ", this.parentNode.parentNode)");
|
.removeCreator(index, ev.currentTarget.parentNode.parentNode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
hbox.appendChild(removeButton);
|
hbox.appendChild(removeButton);
|
||||||
|
|
||||||
// Plus (+) button
|
// Plus (+) button
|
||||||
var addButton = document.createElement('label');
|
var addButton = document.createElement('label');
|
||||||
|
addButton.setAttribute('ztabindex', tabindex + 4);
|
||||||
addButton.setAttribute("value","+");
|
addButton.setAttribute("value","+");
|
||||||
addButton.setAttribute("class", "zotero-clicky zotero-clicky-plus");
|
addButton.setAttribute('role', 'button');
|
||||||
|
addButton.setAttribute('class', 'zotero-clicky zotero-focusable zotero-clicky-plus');
|
||||||
|
addButton.setAttribute('onkeypress', 'return document.getBindingParent(this).handleKeyPress(event)');
|
||||||
// If row isn't saved, don't let user add more
|
// If row isn't saved, don't let user add more
|
||||||
if (unsaved) {
|
if (unsaved) {
|
||||||
this.disableButton(addButton);
|
this.disableButton(addButton);
|
||||||
|
|
@ -958,7 +981,11 @@
|
||||||
button.style.background = `url("chrome://zotero/skin/textfield-dual${Zotero.hiDPISuffix}.png") center/21px auto no-repeat`;
|
button.style.background = `url("chrome://zotero/skin/textfield-dual${Zotero.hiDPISuffix}.png") center/21px auto no-repeat`;
|
||||||
button.setAttribute('tooltiptext', Zotero.getString('pane.item.switchFieldMode.two'));
|
button.setAttribute('tooltiptext', Zotero.getString('pane.item.switchFieldMode.two'));
|
||||||
lastName.setAttribute('fieldMode', '1');
|
lastName.setAttribute('fieldMode', '1');
|
||||||
button.setAttribute('onclick', "document.getBindingParent(this).switchCreatorMode(Zotero.getAncestorByTagName(this, 'row'), 0, false, true)");
|
button.onclick = (ev) => {
|
||||||
|
document
|
||||||
|
.getBindingParent(ev.currentTarget)
|
||||||
|
.switchCreatorMode(Zotero.getAncestorByTagName(ev.currentTarget, 'row'), 0, false, true);
|
||||||
|
};
|
||||||
lastName.setAttribute('flex', '1');
|
lastName.setAttribute('flex', '1');
|
||||||
delete lastName.style.width;
|
delete lastName.style.width;
|
||||||
delete lastName.style.maxWidth;
|
delete lastName.style.maxWidth;
|
||||||
|
|
@ -998,7 +1025,11 @@
|
||||||
button.style.background = `url("chrome://zotero/skin/textfield-single${Zotero.hiDPISuffix}.png") center/21px auto no-repeat`;
|
button.style.background = `url("chrome://zotero/skin/textfield-single${Zotero.hiDPISuffix}.png") center/21px auto no-repeat`;
|
||||||
button.setAttribute('tooltiptext', Zotero.getString('pane.item.switchFieldMode.one'));
|
button.setAttribute('tooltiptext', Zotero.getString('pane.item.switchFieldMode.one'));
|
||||||
lastName.setAttribute('fieldMode', '0');
|
lastName.setAttribute('fieldMode', '0');
|
||||||
button.setAttribute('onclick', "document.getBindingParent(this).switchCreatorMode(Zotero.getAncestorByTagName(this, 'row'), 1, false, true)");
|
button.onclick = (ev) => {
|
||||||
|
document
|
||||||
|
.getBindingParent(ev.currentTarget)
|
||||||
|
.switchCreatorMode(Zotero.getAncestorByTagName(ev.currentTarget, 'row'), 1, false, true)
|
||||||
|
};
|
||||||
lastName.setAttribute('flex', '0');
|
lastName.setAttribute('flex', '0');
|
||||||
|
|
||||||
// appropriately truncate lastName
|
// appropriately truncate lastName
|
||||||
|
|
@ -1721,6 +1752,19 @@
|
||||||
var target = event.target;
|
var target = event.target;
|
||||||
var focused = document.commandDispatcher.focusedElement;
|
var focused = document.commandDispatcher.focusedElement;
|
||||||
|
|
||||||
|
if ((event.key == 'ArrowUp' || event.key === 'ArrowDown')
|
||||||
|
&& target.classList.contains('creator-type-label')) {
|
||||||
|
event.preventDefault();
|
||||||
|
target.click();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.key === ' ' && target.classList.contains('zotero-focusable')) {
|
||||||
|
event.preventDefault();
|
||||||
|
target.click();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
switch (event.keyCode)
|
switch (event.keyCode)
|
||||||
{
|
{
|
||||||
case event.DOM_VK_RETURN:
|
case event.DOM_VK_RETURN:
|
||||||
|
|
@ -1932,8 +1976,6 @@
|
||||||
|
|
||||||
newVal = val;
|
newVal = val;
|
||||||
|
|
||||||
// Reset creator mode settings here so that flex attribute gets reset
|
|
||||||
this.switchCreatorMode(row, (otherFields.fieldMode ? 1 : 0), true);
|
|
||||||
if (Zotero.ItemTypes.getName(this.item.itemTypeID) === "bookSection") {
|
if (Zotero.ItemTypes.getName(this.item.itemTypeID) === "bookSection") {
|
||||||
var creatorTypeLabels = document.getAnonymousNodes(this)[0].getElementsByClassName("creator-type-label");
|
var creatorTypeLabels = document.getAnonymousNodes(this)[0].getElementsByClassName("creator-type-label");
|
||||||
Zotero.debug(creatorTypeLabels[creatorTypeLabels.length-1] + "");
|
Zotero.debug(creatorTypeLabels[creatorTypeLabels.length-1] + "");
|
||||||
|
|
@ -2018,6 +2060,11 @@
|
||||||
// Disassociate textbox from label
|
// Disassociate textbox from label
|
||||||
label.setAttribute('control', elem.getAttribute('id'));
|
label.setAttribute('control', elem.getAttribute('id'));
|
||||||
|
|
||||||
|
if (field == 'creator') {
|
||||||
|
// Set correct flex settings and fieldMode attribute
|
||||||
|
this.switchCreatorMode(row, (otherFields.fieldMode ? 1 : 0), true);
|
||||||
|
}
|
||||||
|
|
||||||
if (this.saveOnEdit) {
|
if (this.saveOnEdit) {
|
||||||
await this.item.saveTx();
|
await this.item.saveTx();
|
||||||
}
|
}
|
||||||
|
|
@ -2295,6 +2342,18 @@
|
||||||
</method>
|
</method>
|
||||||
|
|
||||||
|
|
||||||
|
<method name="focusField">
|
||||||
|
<parameter name="fieldName"/>
|
||||||
|
<body>
|
||||||
|
<![CDATA[
|
||||||
|
let field = document.getAnonymousNodes(this)[0].querySelector(`[fieldname="${fieldName}"][ztabindex]`);
|
||||||
|
if (!field) return false;
|
||||||
|
return this._focusNextField(field.getAttribute('ztabindex'));
|
||||||
|
]]>
|
||||||
|
</body>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Advance the field focus forward or backward
|
Advance the field focus forward or backward
|
||||||
|
|
||||||
|
|
@ -2312,7 +2371,7 @@
|
||||||
tabindex = parseInt(tabindex);
|
tabindex = parseInt(tabindex);
|
||||||
|
|
||||||
// Get all fields with ztabindex attributes
|
// Get all fields with ztabindex attributes
|
||||||
var tabbableFields = box.querySelectorAll('*[ztabindex]');
|
var tabbableFields = box.querySelectorAll('*[ztabindex]:not([disabled=true])');
|
||||||
|
|
||||||
if (!tabbableFields.length) {
|
if (!tabbableFields.length) {
|
||||||
Zotero.debug("No tabbable fields found");
|
Zotero.debug("No tabbable fields found");
|
||||||
|
|
@ -2323,7 +2382,9 @@
|
||||||
if (back) {
|
if (back) {
|
||||||
Zotero.debug('Looking for previous tabindex before ' + tabindex, 4);
|
Zotero.debug('Looking for previous tabindex before ' + tabindex, 4);
|
||||||
for (let i = tabbableFields.length - 1; i >= 0; i--) {
|
for (let i = tabbableFields.length - 1; i >= 0; i--) {
|
||||||
if (parseInt(tabbableFields[i].getAttribute('ztabindex')) < tabindex) {
|
let field = tabbableFields[i];
|
||||||
|
let tabIndexHere = parseInt(field.getAttribute('ztabindex'));
|
||||||
|
if (tabIndexHere !== -1 && tabIndexHere < tabindex) {
|
||||||
next = tabbableFields[i];
|
next = tabbableFields[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -2332,7 +2393,9 @@
|
||||||
else {
|
else {
|
||||||
Zotero.debug('Looking for tabindex ' + tabindex, 4);
|
Zotero.debug('Looking for tabindex ' + tabindex, 4);
|
||||||
for (var pos = 0; pos < tabbableFields.length; pos++) {
|
for (var pos = 0; pos < tabbableFields.length; pos++) {
|
||||||
if (parseInt(tabbableFields[pos].getAttribute('ztabindex')) >= tabindex) {
|
let field = tabbableFields[pos];
|
||||||
|
let tabIndexHere = parseInt(field.getAttribute('ztabindex'));
|
||||||
|
if (tabIndexHere !== -1 && tabIndexHere >= tabindex) {
|
||||||
next = tabbableFields[pos];
|
next = tabbableFields[pos];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -2345,7 +2408,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drop-down needs to be focused
|
// Drop-down needs to be focused
|
||||||
if (next.id == 'item-type-menu') {
|
if (next.id == 'item-type-menu' || next.classList.contains('zotero-focusable')) {
|
||||||
next.focus();
|
next.focus();
|
||||||
}
|
}
|
||||||
// Fields need to be clicked
|
// Fields need to be clicked
|
||||||
|
|
|
||||||
|
|
@ -353,15 +353,16 @@
|
||||||
<body>
|
<body>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
(async () => {
|
(async () => {
|
||||||
let n = 0;
|
|
||||||
while (!this._editorInstance && n++ < 100) {
|
|
||||||
await Zotero.Promise.delay(10);
|
|
||||||
}
|
|
||||||
await this._editorInstance._initPromise;
|
|
||||||
this._iframe.focus();
|
|
||||||
try {
|
try {
|
||||||
|
let n = 0;
|
||||||
|
while (!this._editorInstance && n++ < 100) {
|
||||||
|
await Zotero.Promise.delay(10);
|
||||||
|
}
|
||||||
|
await this._editorInstance._initPromise;
|
||||||
|
this._iframe.focus();
|
||||||
this._editorInstance._iframeWindow.document.querySelector('.toolbar-button-return').focus();
|
this._editorInstance._iframeWindow.document.querySelector('.toolbar-button-return').focus();
|
||||||
} catch(e) {
|
}
|
||||||
|
catch (e) {
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
]]>
|
]]>
|
||||||
|
|
|
||||||
|
|
@ -640,11 +640,8 @@ var CollectionTree = class CollectionTree extends LibraryTree {
|
||||||
this.tree.invalidate();
|
this.tree.invalidate();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (action == 'refresh') {
|
if (action == 'refresh' && type != 'trash') {
|
||||||
// If trash is refreshed, we probably need to update the icon from full to empty
|
// Trash handled below
|
||||||
if (type == 'trash') {
|
|
||||||
this.tree.invalidate();
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (type == 'feed' && (action == 'unreadCountUpdated' || action == 'statusChanged')) {
|
if (type == 'feed' && (action == 'unreadCountUpdated' || action == 'statusChanged')) {
|
||||||
|
|
@ -826,6 +823,11 @@ var CollectionTree = class CollectionTree extends LibraryTree {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (action == 'refresh' && type == 'trash') {
|
||||||
|
// We need to update the trash's status (full or empty), and if empty,
|
||||||
|
// the row might be removed
|
||||||
|
await this.reload();
|
||||||
|
}
|
||||||
|
|
||||||
this.forceUpdate();
|
this.forceUpdate();
|
||||||
var promise = this.waitForSelect();
|
var promise = this.waitForSelect();
|
||||||
|
|
@ -839,6 +841,7 @@ var CollectionTree = class CollectionTree extends LibraryTree {
|
||||||
* @param ids {String[]} list of row ids to be highlighted
|
* @param ids {String[]} list of row ids to be highlighted
|
||||||
*/
|
*/
|
||||||
async setHighlightedRows(ids) {
|
async setHighlightedRows(ids) {
|
||||||
|
if (this._editing) return;
|
||||||
try {
|
try {
|
||||||
this._highlightedRows = new Set();
|
this._highlightedRows = new Set();
|
||||||
|
|
||||||
|
|
@ -1614,7 +1617,7 @@ var CollectionTree = class CollectionTree extends LibraryTree {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let newAttachment = Zotero.Attachments.copyAttachmentToLibrary(item, targetLibraryID);
|
let newAttachment = await Zotero.Attachments.copyAttachmentToLibrary(item, targetLibraryID);
|
||||||
if (options.annotations) {
|
if (options.annotations) {
|
||||||
await Zotero.Items.copyChildItems(item, newAttachment);
|
await Zotero.Items.copyChildItems(item, newAttachment);
|
||||||
}
|
}
|
||||||
|
|
@ -2306,7 +2309,7 @@ var CollectionTree = class CollectionTree extends LibraryTree {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showTrash) {
|
if (showTrash) {
|
||||||
let deletedItems = await Zotero.Items.getDeleted(libraryID);
|
let deletedItems = await Zotero.Items.getDeleted(libraryID, true);
|
||||||
if (deletedItems.length || Zotero.Prefs.get("showTrashWhenEmpty")) {
|
if (deletedItems.length || Zotero.Prefs.get("showTrashWhenEmpty")) {
|
||||||
var ref = {
|
var ref = {
|
||||||
libraryID: libraryID
|
libraryID: libraryID
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ function AnnotationBox({ data }) {
|
||||||
<div className="title">{Zotero.getString('itemTypes.annotation')}</div>
|
<div className="title">{Zotero.getString('itemTypes.annotation')}</div>
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<div className="header">
|
<div className="header">
|
||||||
<div>{Zotero.getString('citation.locator.page')} {data.pageLabel}</div>
|
<div>{Zotero.Cite.getLocatorString('page')} {data.pageLabel}</div>
|
||||||
</div>
|
</div>
|
||||||
{data.text !== undefined
|
{data.text !== undefined
|
||||||
? <div className="text" style={textStyle}>{data.text}</div>
|
? <div className="text" style={textStyle}>{data.text}</div>
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,7 @@ i('TreeitemThesis', 'chrome://zotero/skin/treeitem-thesis.png');
|
||||||
i('TreeitemTvBroadcast', 'chrome://zotero/skin/treeitem-tvBroadcast.png', false);
|
i('TreeitemTvBroadcast', 'chrome://zotero/skin/treeitem-tvBroadcast.png', false);
|
||||||
i('TreeitemVideoRecording', 'chrome://zotero/skin/treeitem-videoRecording.png', false);
|
i('TreeitemVideoRecording', 'chrome://zotero/skin/treeitem-videoRecording.png', false);
|
||||||
i('TreeitemWebpageGray', 'chrome://zotero/skin/treeitem-webpage-gray.png');
|
i('TreeitemWebpageGray', 'chrome://zotero/skin/treeitem-webpage-gray.png');
|
||||||
i('TreeitemWebpage', 'chrome://zotero/skin/treeitem-webpage.png', false);
|
i('TreeitemWebpage', 'chrome://zotero/skin/treeitem-webpage.png');
|
||||||
|
|
||||||
// Treesource
|
// Treesource
|
||||||
i('TreesourceBucket', 'chrome://zotero/skin/treesource-bucket.png', false);
|
i('TreesourceBucket', 'chrome://zotero/skin/treesource-bucket.png', false);
|
||||||
|
|
|
||||||
|
|
@ -235,7 +235,7 @@ const TabBar = forwardRef(function (props, ref) {
|
||||||
|
|
||||||
function handleWheel(event) {
|
function handleWheel(event) {
|
||||||
// Normalize wheel speed
|
// Normalize wheel speed
|
||||||
let x = event.deltaX;
|
let x = event.deltaX || event.deltaY;
|
||||||
if (x && event.deltaMode) {
|
if (x && event.deltaMode) {
|
||||||
if (event.deltaMode === 1) {
|
if (event.deltaMode === 1) {
|
||||||
x *= 20;
|
x *= 20;
|
||||||
|
|
@ -302,7 +302,10 @@ const TabBar = forwardRef(function (props, ref) {
|
||||||
onWheel={handleWheel}
|
onWheel={handleWheel}
|
||||||
>
|
>
|
||||||
<div className="pinned-tabs">
|
<div className="pinned-tabs">
|
||||||
<div className="tabs">
|
<div
|
||||||
|
className="tabs"
|
||||||
|
onMouseOut={handleTabBarMouseOut}
|
||||||
|
>
|
||||||
{tabs.length ? renderTab(tabs[0], 0) : null}
|
{tabs.length ? renderTab(tabs[0], 0) : null}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -660,7 +660,14 @@ class VirtualizedTable extends React.Component {
|
||||||
this._isMouseDrag = true;
|
this._isMouseDrag = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
_onDragEnd = () => {
|
_onDragEnd = async () => {
|
||||||
|
// macOS force-click sometimes causes a second mouseup event to be fired some time later
|
||||||
|
// causing a collection change on dragend, so we add a delay here. It shouldn't cause any issues
|
||||||
|
// because isMouseDrag is only used in mouseup handler to exactly prevent from accidentally switching
|
||||||
|
// selection after dragend.
|
||||||
|
if (Zotero.isMac) {
|
||||||
|
await Zotero.Promise.delay(500);
|
||||||
|
}
|
||||||
this._isMouseDrag = false;
|
this._isMouseDrag = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -740,6 +747,7 @@ class VirtualizedTable extends React.Component {
|
||||||
this.selection.pivot = index;
|
this.selection.pivot = index;
|
||||||
this.invalidateRow(previousFocused);
|
this.invalidateRow(previousFocused);
|
||||||
this.invalidateRow(index);
|
this.invalidateRow(index);
|
||||||
|
this.selection._updateTree(shouldDebounce);
|
||||||
}
|
}
|
||||||
// Normal selection
|
// Normal selection
|
||||||
else if (!toggleSelection) {
|
else if (!toggleSelection) {
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,9 @@ var ZoteroContextPane = new function () {
|
||||||
var _itemContexts = [];
|
var _itemContexts = [];
|
||||||
var _notesContexts = [];
|
var _notesContexts = [];
|
||||||
|
|
||||||
|
var _globalDeckIndex = [];
|
||||||
|
var _preventGlobalDeckChange = false;
|
||||||
|
|
||||||
// Using attribute instead of property to set 'selectedIndex'
|
// Using attribute instead of property to set 'selectedIndex'
|
||||||
// is more reliable
|
// is more reliable
|
||||||
|
|
||||||
|
|
@ -176,6 +179,20 @@ var ZoteroContextPane = new function () {
|
||||||
if (Zotero_Tabs.deck.children.length == 1) {
|
if (Zotero_Tabs.deck.children.length == 1) {
|
||||||
_notesContexts.forEach(x => x.notesListRef.current.setExpanded(false));
|
_notesContexts.forEach(x => x.notesListRef.current.setExpanded(false));
|
||||||
}
|
}
|
||||||
|
// Close tab specific notes if tab id no longer exists, but
|
||||||
|
// do that only when unloaded tab is reloaded
|
||||||
|
setTimeout(() => {
|
||||||
|
var contextNodes = Array.from(_notesPaneDeck.children);
|
||||||
|
for (let contextNode of contextNodes) {
|
||||||
|
var nodes = Array.from(contextNode.querySelector('.zotero-context-pane-tab-notes-deck').children);
|
||||||
|
for (let node of nodes) {
|
||||||
|
var tabID = node.getAttribute('data-tab-id');
|
||||||
|
if (!document.getElementById(tabID)) {
|
||||||
|
node.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else if (action == 'select') {
|
else if (action == 'select') {
|
||||||
// It seems that changing `hidden` or `collapsed` values might
|
// It seems that changing `hidden` or `collapsed` values might
|
||||||
|
|
@ -188,6 +205,14 @@ var ZoteroContextPane = new function () {
|
||||||
_tabCover.hidden = true;
|
_tabCover.hidden = true;
|
||||||
}
|
}
|
||||||
else if (Zotero_Tabs.selectedType == 'reader') {
|
else if (Zotero_Tabs.selectedType == 'reader') {
|
||||||
|
if (_panesDeck.selectedIndex == 1
|
||||||
|
&& _notesPaneDeck.selectedPanel.selectedIndex != 2
|
||||||
|
&& !_preventGlobalDeckChange) {
|
||||||
|
let libraryID = _notesPaneDeck.selectedPanel.getAttribute('data-library-id');
|
||||||
|
_globalDeckIndex[libraryID] = _notesPaneDeck.selectedPanel.selectedIndex;
|
||||||
|
}
|
||||||
|
_preventGlobalDeckChange = false;
|
||||||
|
|
||||||
var reader = Zotero.Reader.getByTabID(Zotero_Tabs.selectedID);
|
var reader = Zotero.Reader.getByTabID(Zotero_Tabs.selectedID);
|
||||||
if (reader) {
|
if (reader) {
|
||||||
_tabCover.hidden = false;
|
_tabCover.hidden = false;
|
||||||
|
|
@ -207,11 +232,25 @@ var ZoteroContextPane = new function () {
|
||||||
var notesContext = _getNotesContext(attachment.libraryID);
|
var notesContext = _getNotesContext(attachment.libraryID);
|
||||||
notesContext.updateFromCache();
|
notesContext.updateFromCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let tabNotesDeck = _notesPaneDeck.selectedPanel.querySelector('.zotero-context-pane-tab-notes-deck');
|
||||||
|
let selectedIndex = Array.from(tabNotesDeck.children).findIndex(x => x.getAttribute('data-tab-id') == ids[0]);
|
||||||
|
if (selectedIndex != -1) {
|
||||||
|
tabNotesDeck.setAttribute('selectedIndex', selectedIndex);
|
||||||
|
_notesPaneDeck.selectedPanel.setAttribute('selectedIndex', 2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let libraryID = _notesPaneDeck.selectedPanel.getAttribute('data-library-id');
|
||||||
|
_notesPaneDeck.selectedPanel.setAttribute('selectedIndex', _globalDeckIndex[libraryID] || 0);
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
_contextPaneSplitter.setAttribute('hidden', false);
|
_contextPaneSplitter.setAttribute('hidden', false);
|
||||||
// It seems that on heavy load (i.e. syncing) the line below doesn't set the correct value
|
|
||||||
|
_contextPane.setAttribute('collapsed', !(_contextPaneSplitter.getAttribute('state') != 'collapsed'));
|
||||||
|
// It seems that on heavy load (i.e. syncing) the line below doesn't set the correct value,
|
||||||
|
// therefore we repeat the same operation at the end of JS message queue
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
_contextPane.setAttribute('collapsed', !(_contextPaneSplitter.getAttribute('state') != 'collapsed'));
|
_contextPane.setAttribute('collapsed', !(_contextPaneSplitter.getAttribute('state') != 'collapsed'));
|
||||||
});
|
});
|
||||||
|
|
@ -243,9 +282,14 @@ var ZoteroContextPane = new function () {
|
||||||
|
|
||||||
if (splitter.getAttribute('state') != 'collapsed') {
|
if (splitter.getAttribute('state') != 'collapsed') {
|
||||||
if (_panesDeck.selectedIndex == 1) {
|
if (_panesDeck.selectedIndex == 1) {
|
||||||
var node = _notesPaneDeck.selectedPanel;
|
var libraryContext = _notesPaneDeck.selectedPanel;
|
||||||
if (node.selectedIndex == 1) {
|
// Global note
|
||||||
return node.querySelector('zoteronoteeditor');
|
if (libraryContext.selectedIndex == 1) {
|
||||||
|
return libraryContext.querySelector('zoteronoteeditor');
|
||||||
|
}
|
||||||
|
// Tab specific child note
|
||||||
|
else if (libraryContext.selectedIndex == 2) {
|
||||||
|
return libraryContext.querySelector('.zotero-context-pane-tab-notes-deck').selectedPanel.querySelector('zoteronoteeditor');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -420,11 +464,20 @@ var ZoteroContextPane = new function () {
|
||||||
editor.setAttribute('flex', 1);
|
editor.setAttribute('flex', 1);
|
||||||
noteContainer.append(title, editor);
|
noteContainer.append(title, editor);
|
||||||
|
|
||||||
|
var tabNotesContainer = document.createElement('vbox');
|
||||||
|
var title = document.createElement('vbox');
|
||||||
|
title.className = 'zotero-context-pane-editor-parent-line';
|
||||||
|
let tabNotesDeck = document.createElement('deck');
|
||||||
|
tabNotesDeck.className = 'zotero-context-pane-tab-notes-deck';
|
||||||
|
tabNotesDeck.setAttribute('flex', 1);
|
||||||
|
tabNotesContainer.append(title, tabNotesDeck);
|
||||||
|
|
||||||
let contextNode = document.createElement('deck');
|
let contextNode = document.createElement('deck');
|
||||||
contextNode.append(list, noteContainer);
|
contextNode.append(list, noteContainer, tabNotesContainer);
|
||||||
_notesPaneDeck.append(contextNode);
|
_notesPaneDeck.append(contextNode);
|
||||||
|
|
||||||
contextNode.className = 'context-node';
|
contextNode.className = 'context-node';
|
||||||
|
contextNode.setAttribute('data-library-id', libraryID);
|
||||||
contextNode.setAttribute('selectedIndex', 0);
|
contextNode.setAttribute('selectedIndex', 0);
|
||||||
|
|
||||||
editor.returnHandler = () => {
|
editor.returnHandler = () => {
|
||||||
|
|
@ -440,8 +493,15 @@ var ZoteroContextPane = new function () {
|
||||||
if (!attachment) {
|
if (!attachment) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
var annotations = attachment.getAnnotations().filter(x => x.annotationType != 'ink');
|
||||||
|
if (!annotations.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
var note = await Zotero.EditorInstance.createNoteFromAnnotations(
|
var note = await Zotero.EditorInstance.createNoteFromAnnotations(
|
||||||
attachment.getAnnotations().filter(x => x.annotationType != 'ink'), child && attachment.parentID
|
annotations,
|
||||||
|
{
|
||||||
|
parentID: child && attachment.parentID
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
_updateAddToNote();
|
_updateAddToNote();
|
||||||
|
|
@ -449,7 +509,7 @@ var ZoteroContextPane = new function () {
|
||||||
input.value = '';
|
input.value = '';
|
||||||
_updateNotesList();
|
_updateNotesList();
|
||||||
|
|
||||||
_setPinnedNote(note.id);
|
_setPinnedNote(note);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _createNote(child) {
|
function _createNote(child) {
|
||||||
|
|
@ -463,10 +523,7 @@ var ZoteroContextPane = new function () {
|
||||||
}
|
}
|
||||||
item.parentID = attachment.parentID;
|
item.parentID = attachment.parentID;
|
||||||
}
|
}
|
||||||
editor.mode = 'edit';
|
_setPinnedNote(item);
|
||||||
editor.item = item;
|
|
||||||
editor.parentItem = null;
|
|
||||||
editor.focus();
|
|
||||||
_updateAddToNote();
|
_updateAddToNote();
|
||||||
|
|
||||||
input.value = '';
|
input.value = '';
|
||||||
|
|
@ -672,7 +729,10 @@ var ZoteroContextPane = new function () {
|
||||||
<NotesList
|
<NotesList
|
||||||
ref={notesListRef}
|
ref={notesListRef}
|
||||||
onClick={(id) => {
|
onClick={(id) => {
|
||||||
_setPinnedNote(id);
|
let item = Zotero.Items.get(id);
|
||||||
|
if (item) {
|
||||||
|
_setPinnedNote(item);
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
onContextMenu={(id, event) => {
|
onContextMenu={(id, event) => {
|
||||||
document.getElementById('context-pane-list-move-to-trash').setAttribute('disabled', readOnly);
|
document.getElementById('context-pane-list-move-to-trash').setAttribute('disabled', readOnly);
|
||||||
|
|
@ -727,21 +787,63 @@ var ZoteroContextPane = new function () {
|
||||||
return !Zotero.Libraries.get(libraryID).editable;
|
return !Zotero.Libraries.get(libraryID).editable;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _setPinnedNote(itemID) {
|
function _setPinnedNote(item) {
|
||||||
var item = Zotero.Items.get(itemID);
|
|
||||||
if (!item) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var readOnly = _isLibraryReadOnly(item.libraryID);
|
var readOnly = _isLibraryReadOnly(item.libraryID);
|
||||||
var context = _getNotesContext(item.libraryID);
|
var context = _getNotesContext(item.libraryID);
|
||||||
if (context) {
|
if (context) {
|
||||||
var { editor, node } = context;
|
var { editor, node } = context;
|
||||||
node.setAttribute('selectedIndex', 1);
|
|
||||||
editor.mode = readOnly ? 'view' : 'edit';
|
|
||||||
editor.item = item;
|
|
||||||
editor.parentItem = null;
|
|
||||||
|
|
||||||
node.querySelector('.zotero-context-pane-editor-parent-line').innerHTML = '';
|
let isChild = false;
|
||||||
|
var reader = Zotero.Reader.getByTabID(Zotero_Tabs.selectedID);
|
||||||
|
if (reader) {
|
||||||
|
let attachment = Zotero.Items.get(reader.itemID);
|
||||||
|
if (attachment.parentItemID == item.parentItemID) {
|
||||||
|
isChild = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var tabNotesDeck = _notesPaneDeck.selectedPanel.querySelector('.zotero-context-pane-tab-notes-deck');
|
||||||
|
var parentTitleContainer;
|
||||||
|
if (isChild) {
|
||||||
|
var vbox = document.createElement('vbox');
|
||||||
|
vbox.setAttribute('data-tab-id', Zotero_Tabs.selectedID);
|
||||||
|
vbox.style.display = 'flex';
|
||||||
|
|
||||||
|
editor = document.createElement('zoteronoteeditor');
|
||||||
|
editor.style.display = 'flex';
|
||||||
|
editor.style.width = '100%';
|
||||||
|
vbox.append(editor);
|
||||||
|
|
||||||
|
tabNotesDeck.append(vbox);
|
||||||
|
|
||||||
|
editor.mode = readOnly ? 'view' : 'edit';
|
||||||
|
editor.item = item;
|
||||||
|
editor.parentItem = null;
|
||||||
|
editor.returnHandler = () => {
|
||||||
|
_panesDeck.setAttribute('selectedIndex', 1);
|
||||||
|
_notesPaneDeck.selectedPanel.setAttribute('selectedIndex', 0);
|
||||||
|
vbox.remove();
|
||||||
|
_updateAddToNote();
|
||||||
|
_preventGlobalDeckChange = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
_notesPaneDeck.selectedPanel.setAttribute('selectedIndex', 2);
|
||||||
|
tabNotesDeck.setAttribute('selectedIndex', tabNotesDeck.children.length - 1);
|
||||||
|
|
||||||
|
parentTitleContainer = _notesPaneDeck.selectedPanel.children[2].querySelector('.zotero-context-pane-editor-parent-line');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
node.setAttribute('selectedIndex', 1);
|
||||||
|
editor.mode = readOnly ? 'view' : 'edit';
|
||||||
|
editor.item = item;
|
||||||
|
editor.parentItem = null;
|
||||||
|
|
||||||
|
parentTitleContainer = node.querySelector('.zotero-context-pane-editor-parent-line');
|
||||||
|
}
|
||||||
|
|
||||||
|
editor.focus();
|
||||||
|
|
||||||
|
parentTitleContainer.innerHTML = '';
|
||||||
var parentItem = item.parentItem;
|
var parentItem = item.parentItem;
|
||||||
if (parentItem) {
|
if (parentItem) {
|
||||||
var container = document.createElementNS(HTML_NS, 'div');
|
var container = document.createElementNS(HTML_NS, 'div');
|
||||||
|
|
@ -752,7 +854,7 @@ var ZoteroContextPane = new function () {
|
||||||
title.append(parentItem.getDisplayTitle());
|
title.append(parentItem.getDisplayTitle());
|
||||||
title.className = 'parent-title';
|
title.className = 'parent-title';
|
||||||
container.append(img, title);
|
container.append(img, title);
|
||||||
node.querySelector('.zotero-context-pane-editor-parent-line').append(container);
|
parentTitleContainer.append(container);
|
||||||
}
|
}
|
||||||
_updateAddToNote();
|
_updateAddToNote();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -238,26 +238,29 @@ var Zotero_File_Interface = new function() {
|
||||||
/*
|
/*
|
||||||
* exports items to clipboard
|
* exports items to clipboard
|
||||||
*/
|
*/
|
||||||
function exportItemsToClipboard(items, translatorID) {
|
function exportItemsToClipboard(items, format) {
|
||||||
function _translate(items, translatorID, callback) {
|
function _translate(items, format, callback) {
|
||||||
let translation = new Zotero.Translate.Export();
|
let translation = new Zotero.Translate.Export();
|
||||||
translation.setItems(items.slice());
|
translation.setItems(items.slice());
|
||||||
translation.setTranslator(translatorID);
|
translation.setTranslator(format.id);
|
||||||
|
if (format.options) {
|
||||||
|
translation.setDisplayOptions(format.options);
|
||||||
|
}
|
||||||
translation.setHandler("done", callback);
|
translation.setHandler("done", callback);
|
||||||
translation.translate();
|
translation.translate();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If translating with virtual "Markdown + Rich Text" translator, use Note Markdown and
|
// If translating with virtual "Markdown + Rich Text" translator, use Note Markdown and
|
||||||
// Note HTML instead
|
// Note HTML instead
|
||||||
if (translatorID == Zotero.Translators.TRANSLATOR_ID_MARKDOWN_AND_RICH_TEXT) {
|
if (format.id == Zotero.Translators.TRANSLATOR_ID_MARKDOWN_AND_RICH_TEXT) {
|
||||||
translatorID = Zotero.Translators.TRANSLATOR_ID_NOTE_MARKDOWN;
|
let markdownFormat = { mode: 'export', id: Zotero.Translators.TRANSLATOR_ID_NOTE_MARKDOWN, options: format.markdownOptions };
|
||||||
_translate(items, translatorID, (obj, worked) => {
|
let htmlFormat = { mode: 'export', id: Zotero.Translators.TRANSLATOR_ID_NOTE_HTML, options: format.htmlOptions };
|
||||||
|
_translate(items, markdownFormat, (obj, worked) => {
|
||||||
if (!worked) {
|
if (!worked) {
|
||||||
Zotero.log(Zotero.getString('fileInterface.exportError'), 'warning');
|
Zotero.log(Zotero.getString('fileInterface.exportError'), 'warning');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
translatorID = Zotero.Translators.TRANSLATOR_ID_NOTE_HTML;
|
_translate(items, htmlFormat, (obj2, worked) => {
|
||||||
_translate(items, translatorID, (obj2, worked) => {
|
|
||||||
if (!worked) {
|
if (!worked) {
|
||||||
Zotero.log(Zotero.getString('fileInterface.exportError'), 'warning');
|
Zotero.log(Zotero.getString('fileInterface.exportError'), 'warning');
|
||||||
return;
|
return;
|
||||||
|
|
@ -293,14 +296,14 @@ var Zotero_File_Interface = new function() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_translate(items, translatorID, (obj, worked) => {
|
_translate(items, format, (obj, worked) => {
|
||||||
if (!worked) {
|
if (!worked) {
|
||||||
Zotero.log(Zotero.getString('fileInterface.exportError'), 'warning');
|
Zotero.log(Zotero.getString('fileInterface.exportError'), 'warning');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let text = obj.string;
|
let text = obj.string;
|
||||||
// For Note HTML translator use body content only
|
// For Note HTML translator use body content only
|
||||||
if (translatorID == Zotero.Translators.TRANSLATOR_ID_NOTE_HTML) {
|
if (format.id == Zotero.Translators.TRANSLATOR_ID_NOTE_HTML) {
|
||||||
let parser = Components.classes['@mozilla.org/xmlextras/domparser;1']
|
let parser = Components.classes['@mozilla.org/xmlextras/domparser;1']
|
||||||
.createInstance(Components.interfaces.nsIDOMParser);
|
.createInstance(Components.interfaces.nsIDOMParser);
|
||||||
let doc = parser.parseFromString(text, 'text/html');
|
let doc = parser.parseFromString(text, 'text/html');
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,9 @@ const parseCitavi5Quads = (quadsRaw) => {
|
||||||
const ImportCitaviAnnotatons = async (translation) => {
|
const ImportCitaviAnnotatons = async (translation) => {
|
||||||
const IDMap = translation._itemSaver._IDMap;
|
const IDMap = translation._itemSaver._IDMap;
|
||||||
const ZU = translation._sandboxZotero.Utilities;
|
const ZU = translation._sandboxZotero.Utilities;
|
||||||
|
|
||||||
|
// stream might be closed by now, re-init to make sure getXML() works
|
||||||
|
translation._io.init('xml/dom');
|
||||||
const doc = translation._sandboxZotero.getXML();
|
const doc = translation._sandboxZotero.getXML();
|
||||||
const isCitavi5 = ZU.xpathText(doc, '//CitaviExchangeData/@Version').startsWith('5');
|
const isCitavi5 = ZU.xpathText(doc, '//CitaviExchangeData/@Version').startsWith('5');
|
||||||
var annotationNodes = ZU.xpath(doc, '//Annotations/Annotation');
|
var annotationNodes = ZU.xpath(doc, '//Annotations/Annotation');
|
||||||
|
|
@ -35,11 +38,23 @@ const ImportCitaviAnnotatons = async (translation) => {
|
||||||
const quadsRaw = ZU.xpathText(annotationNodes[i], './Quads');
|
const quadsRaw = ZU.xpathText(annotationNodes[i], './Quads');
|
||||||
const locationID = ZU.xpathText(annotationNodes[i], './LocationID');
|
const locationID = ZU.xpathText(annotationNodes[i], './LocationID');
|
||||||
|
|
||||||
const location = ZU.xpath(doc, `//Locations/Location[@${isCitavi5 ? 'ID' : 'id'}='${locationID}']`)[0];
|
const location = ZU.xpath(doc, `//Locations/Location[@id='${locationID}']|//Locations/Location[@ID='${locationID}']`)[0];
|
||||||
|
|
||||||
|
if (!location) {
|
||||||
|
Zotero.debug(`Missing <Location> entry for annotation ${id}, skipping...`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const referenceID = ZU.xpathText(location, './ReferenceID');
|
const referenceID = ZU.xpathText(location, './ReferenceID');
|
||||||
const entityLink = ZU.xpath(doc, `//EntityLinks/EntityLink[TargetID='${id}']`)[0];
|
const entityLink = ZU.xpath(doc, `//EntityLinks/EntityLink[TargetID='${id}']`)[0];
|
||||||
|
|
||||||
|
if (!entityLink) {
|
||||||
|
Zotero.debug(`Missing <EntityLink> entry for annotation ${id}, skipping...`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const entitySourceID = ZU.xpathText(entityLink, './SourceID');
|
const entitySourceID = ZU.xpathText(entityLink, './SourceID');
|
||||||
const knowledgeItem = ZU.xpath(doc, `//KnowledgeItems/KnowledgeItem[@${isCitavi5 ? 'ID' : 'id'}='${entitySourceID}']`)[0];
|
const knowledgeItem = ZU.xpath(doc, `//KnowledgeItems/KnowledgeItem[@id='${entitySourceID}']|//KnowledgeItems/KnowledgeItem[@ID='${entitySourceID}']`)[0];
|
||||||
const keywordsIDsText = ZU.xpathText(doc, `//KnowledgeItemKeywords/OnetoN[starts-with(text(), "${entitySourceID}")]`);
|
const keywordsIDsText = ZU.xpathText(doc, `//KnowledgeItemKeywords/OnetoN[starts-with(text(), "${entitySourceID}")]`);
|
||||||
const keywords = keywordsIDsText
|
const keywords = keywordsIDsText
|
||||||
? keywordsIDsText
|
? keywordsIDsText
|
||||||
|
|
@ -135,15 +150,21 @@ const ImportCitaviAnnotatons = async (translation) => {
|
||||||
annotations.push(annotation);
|
annotations.push(annotation);
|
||||||
});
|
});
|
||||||
|
|
||||||
annotations = await Zotero.PDFWorker.processCitaviAnnotations(
|
|
||||||
itemAttachment.getFilePath(), annotations
|
|
||||||
);
|
|
||||||
|
|
||||||
annotations.forEach((annotation) => {
|
try {
|
||||||
promises.push(Zotero.Annotations.saveFromJSON(
|
// eslint-disable-next-line no-await-in-loop
|
||||||
itemAttachment, annotation, { skipSelect: true }
|
annotations = await Zotero.PDFWorker.processCitaviAnnotations(
|
||||||
));
|
itemAttachment.getFilePath(), annotations
|
||||||
});
|
);
|
||||||
|
annotations.forEach((annotation) => {
|
||||||
|
promises.push(Zotero.Annotations.saveFromJSON(
|
||||||
|
itemAttachment, annotation, { skipSelect: true }
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
Zotero.debug(`Could not process annotations for attachment item ${itemAttachment.key} (file path: ${itemAttachment.getFilePath()})`);
|
||||||
|
}
|
||||||
|
|
||||||
progress = baseProgress + Math.ceil((i / annotationNodes.length) * stageProgress);
|
progress = baseProgress + Math.ceil((i / annotationNodes.length) * stageProgress);
|
||||||
translation._runHandler('itemDone', []);
|
translation._runHandler('itemDone', []);
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,11 @@ var Zotero_Import_Wizard = {
|
||||||
Zotero.Translators.init(); // async
|
Zotero.Translators.init(); // async
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onCancel: function () {
|
||||||
|
if (this._translation && this._translation.interrupt) {
|
||||||
|
this._translation.interrupt();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
onModeChosen: async function () {
|
onModeChosen: async function () {
|
||||||
var wizard = this._wizard;
|
var wizard = this._wizard;
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||||
title="&zotero.import;"
|
title="&zotero.import;"
|
||||||
|
onwizardcancel="Zotero_Import_Wizard.onCancel()"
|
||||||
onload="Zotero_Import_Wizard.init()">
|
onload="Zotero_Import_Wizard.init()">
|
||||||
|
|
||||||
<script src="../include.js"/>
|
<script src="../include.js"/>
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ const getNextLinkFromResponse = (response) => {
|
||||||
|
|
||||||
const apiFetchUrl = async (tokens, url, headers = {}, options = {}) => {
|
const apiFetchUrl = async (tokens, url, headers = {}, options = {}) => {
|
||||||
headers = { ...headers, Authorization: `Bearer ${tokens.access_token}` };
|
headers = { ...headers, Authorization: `Bearer ${tokens.access_token}` };
|
||||||
options = { ...options, headers };
|
options = { ...options, headers, timeout: 60000 };
|
||||||
const method = 'GET';
|
const method = 'GET';
|
||||||
|
|
||||||
// Run the request. If we see 401 or 403, try to refresh tokens and run the request again
|
// Run the request. If we see 401 or 403, try to refresh tokens and run the request again
|
||||||
|
|
@ -64,16 +64,18 @@ const get = async (tokens, endPoint, params = {}, headers = {}, options = {}) =>
|
||||||
return JSON.parse(response.responseText);
|
return JSON.parse(response.responseText);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getAll = async (tokens, endPoint, params = {}, headers = {}, options = {}) => {
|
const getAll = async (tokens, endPoint, params = {}, headers = {}, options = {}, interruptChecker = () => {}) => {
|
||||||
const PER_PAGE = endPoint === 'annotations' ? 200 : 500;
|
const PER_PAGE = endPoint === 'annotations' ? 200 : 500;
|
||||||
const response = await apiFetch(tokens, endPoint, { ...params, limit: PER_PAGE }, headers, options);
|
const response = await apiFetch(tokens, endPoint, { ...params, limit: PER_PAGE }, headers, options);
|
||||||
var next = getNextLinkFromResponse(response);
|
var next = getNextLinkFromResponse(response);
|
||||||
var data = JSON.parse(response.responseText);
|
var data = JSON.parse(response.responseText);
|
||||||
|
interruptChecker();
|
||||||
|
|
||||||
while (next) {
|
while (next) {
|
||||||
const response = await apiFetchUrl(tokens, next, headers, options); //eslint-disable-line no-await-in-loop
|
const response = await apiFetchUrl(tokens, next, headers, options); //eslint-disable-line no-await-in-loop
|
||||||
data = [...data, ...JSON.parse(response.responseText)];
|
data = [...data, ...JSON.parse(response.responseText)];
|
||||||
next = getNextLinkFromResponse(response);
|
next = getNextLinkFromResponse(response);
|
||||||
|
interruptChecker();
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,29 @@
|
||||||
/* global map:false, mendeleyOnlineMappings:false, mendeleyAPIUtils:false */
|
/* eslint-disable no-await-in-loop, camelcase */
|
||||||
var EXPORTED_SYMBOLS = ["Zotero_Import_Mendeley"];
|
/* global mendeleyDBMaps:false, mendeleyOnlineMappings:false, mendeleyAPIUtils:false */
|
||||||
|
var EXPORTED_SYMBOLS = ["Zotero_Import_Mendeley"]; //eslint-disable-line no-unused-vars
|
||||||
|
|
||||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||||
Components.utils.import("resource://gre/modules/osfile.jsm");
|
Components.utils.import("resource://gre/modules/osfile.jsm");
|
||||||
Services.scriptloader.loadSubScript("chrome://zotero/content/include.js");
|
Services.scriptloader.loadSubScript("chrome://zotero/content/include.js");
|
||||||
Services.scriptloader.loadSubScript("chrome://zotero/content/import/mendeley/mendeleyOnlineMappings.js");
|
Services.scriptloader.loadSubScript("chrome://zotero/content/import/mendeley/mendeleyOnlineMappings.js");
|
||||||
Services.scriptloader.loadSubScript("chrome://zotero/content/import/mendeley/mendeleyAPIUtils.js");
|
Services.scriptloader.loadSubScript("chrome://zotero/content/import/mendeley/mendeleyAPIUtils.js");
|
||||||
|
Services.scriptloader.loadSubScript("chrome://zotero/content/import/mendeley/mendeleySchemaMap.js");
|
||||||
|
|
||||||
const { apiTypeToDBType, apiFieldToDBField } = mendeleyOnlineMappings;
|
const { apiTypeToDBType, apiFieldToDBField } = mendeleyOnlineMappings;
|
||||||
const { apiFetch, get, getAll, getTokens } = mendeleyAPIUtils;
|
const { apiFetch, get, getAll, getTokens } = mendeleyAPIUtils;
|
||||||
|
|
||||||
|
const colorMap = new Map();
|
||||||
|
colorMap.set('rgb(255, 245, 173)', '#ffd400');
|
||||||
|
colorMap.set('#fff5ad', '#ffd400');
|
||||||
|
colorMap.set('rgb(255, 181, 182)', '#ff6666');
|
||||||
|
colorMap.set('#ffb5b6', '#ff6666');
|
||||||
|
colorMap.set('rgb(186, 226, 255)', '#2ea8e5');
|
||||||
|
colorMap.set('#bae2ff', '#2ea8e5');
|
||||||
|
colorMap.set('rgb(211, 194, 255)', '#a28ae5');
|
||||||
|
colorMap.set('#d3c2ff', '#a28ae5');
|
||||||
|
colorMap.set('rgb(220, 255, 176)', '#5fb236');
|
||||||
|
colorMap.set('#dcffb0', '#5fb236');
|
||||||
|
|
||||||
var Zotero_Import_Mendeley = function () {
|
var Zotero_Import_Mendeley = function () {
|
||||||
this.createNewCollection = null;
|
this.createNewCollection = null;
|
||||||
this.linkFiles = null;
|
this.linkFiles = null;
|
||||||
|
|
@ -17,13 +31,32 @@ var Zotero_Import_Mendeley = function () {
|
||||||
this.mendeleyCode = null;
|
this.mendeleyCode = null;
|
||||||
|
|
||||||
this._tokens = null;
|
this._tokens = null;
|
||||||
this._db;
|
this._db = null;
|
||||||
this._file;
|
this._file = null;
|
||||||
this._saveOptions = null;
|
this._saveOptions = null;
|
||||||
this._itemDone;
|
this._itemDone = () => {};
|
||||||
this._progress = 0;
|
this._progress = 0;
|
||||||
this._progressMax;
|
this._progressMax = 0;
|
||||||
this._tmpFilesToDelete = [];
|
this._tmpFilesToDelete = [];
|
||||||
|
this._caller = null;
|
||||||
|
this._interrupted = false;
|
||||||
|
this._totalSize = 0;
|
||||||
|
this._started = Date.now();
|
||||||
|
this._interruptChecker = (tickProgress = false) => {
|
||||||
|
if (this._interrupted) {
|
||||||
|
throw new Error(`Mendeley import interrupted!
|
||||||
|
Started: ${this._started} (${Math.round((Date.now() - this._started) / 1000)}s ago)
|
||||||
|
Progress: ${this._progress} / ${this._progressMax}
|
||||||
|
New items created: ${this.newItems.length}
|
||||||
|
Total size of files to download: ${Math.round(this._totalSize / 1024)}KB
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tickProgress) {
|
||||||
|
this._progress++;
|
||||||
|
this._itemDone();
|
||||||
|
}
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
Zotero_Import_Mendeley.prototype.setLocation = function (file) {
|
Zotero_Import_Mendeley.prototype.setLocation = function (file) {
|
||||||
|
|
@ -32,9 +65,9 @@ Zotero_Import_Mendeley.prototype.setLocation = function (file) {
|
||||||
|
|
||||||
Zotero_Import_Mendeley.prototype.setHandler = function (name, handler) {
|
Zotero_Import_Mendeley.prototype.setHandler = function (name, handler) {
|
||||||
switch (name) {
|
switch (name) {
|
||||||
case 'itemDone':
|
case 'itemDone':
|
||||||
this._itemDone = handler;
|
this._itemDone = handler;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -57,34 +90,16 @@ Zotero_Import_Mendeley.prototype.translate = async function (options = {}) {
|
||||||
...(options.saveOptions || {})
|
...(options.saveOptions || {})
|
||||||
};
|
};
|
||||||
|
|
||||||
if (true) {
|
|
||||||
Services.scriptloader.loadSubScript("chrome://zotero/content/import/mendeley/mendeleySchemaMap.js");
|
|
||||||
}
|
|
||||||
// TEMP: Load uncached from ~/zotero-client for development
|
|
||||||
else {
|
|
||||||
Components.utils.import("resource://gre/modules/FileUtils.jsm");
|
|
||||||
let file = FileUtils.getDir("Home", []);
|
|
||||||
file = OS.Path.join(file.path, 'zotero-client', 'chrome', 'content', 'zotero', 'import', 'mendeley', 'mendeleySchemaMap.js');
|
|
||||||
let fileURI = OS.Path.toFileURI(file);
|
|
||||||
let xmlhttp = await Zotero.HTTP.request(
|
|
||||||
'GET',
|
|
||||||
fileURI,
|
|
||||||
{
|
|
||||||
noCache: true,
|
|
||||||
responseType: 'text'
|
|
||||||
}
|
|
||||||
);
|
|
||||||
eval(xmlhttp.response);
|
|
||||||
}
|
|
||||||
|
|
||||||
const libraryID = options.libraryID || Zotero.Libraries.userLibraryID;
|
const libraryID = options.libraryID || Zotero.Libraries.userLibraryID;
|
||||||
const { key: rootCollectionKey } = options.collections
|
const { key: rootCollectionKey } = options.collections
|
||||||
? Zotero.Collections.getLibraryAndKeyFromID(options.collections[0])
|
? Zotero.Collections.getLibraryAndKeyFromID(options.collections[0])
|
||||||
: {};
|
: {};
|
||||||
|
|
||||||
|
Zotero.debug(`Begining Mendeley import at ${this._started}. libraryID: ${libraryID}, linkFiles: ${this.linkFiles}, rootCollectionKey: ${rootCollectionKey}`);
|
||||||
|
|
||||||
// TODO: Get appropriate version based on schema version
|
// TODO: Get appropriate version based on schema version
|
||||||
const mapVersion = 83;
|
const mapVersion = 83;
|
||||||
map = map[mapVersion];
|
const map = mendeleyDBMaps[mapVersion];
|
||||||
|
|
||||||
const mendeleyGroupID = 0;
|
const mendeleyGroupID = 0;
|
||||||
|
|
||||||
|
|
@ -108,14 +123,22 @@ Zotero_Import_Mendeley.prototype.translate = async function (options = {}) {
|
||||||
throw new Error("Missing import token");
|
throw new Error("Missing import token");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we don't know how long the import will be but want to show progress to give
|
||||||
|
// feedback that import has started so we arbitrary set progress at 2%
|
||||||
|
this._progress = 1;
|
||||||
|
this._progressMax = 50;
|
||||||
|
this._itemDone();
|
||||||
|
|
||||||
const folders = this._tokens
|
const folders = this._tokens
|
||||||
? await this._getFoldersAPI(mendeleyGroupID)
|
? await this._getFoldersAPI(mendeleyGroupID)
|
||||||
: await this._getFoldersDB(mendeleyGroupID);
|
: await this._getFoldersDB(mendeleyGroupID);
|
||||||
|
|
||||||
const collectionJSON = this._foldersToAPIJSON(folders, rootCollectionKey);
|
const collectionJSON = this._foldersToAPIJSON(folders, rootCollectionKey);
|
||||||
const folderKeys = this._getFolderKeys(collectionJSON);
|
const folderKeys = this._getFolderKeys(collectionJSON);
|
||||||
|
|
||||||
await this._saveCollections(libraryID, collectionJSON, folderKeys);
|
await this._saveCollections(libraryID, collectionJSON, folderKeys);
|
||||||
|
|
||||||
|
this._interruptChecker(true);
|
||||||
//
|
//
|
||||||
// Items
|
// Items
|
||||||
//
|
//
|
||||||
|
|
@ -123,40 +146,59 @@ Zotero_Import_Mendeley.prototype.translate = async function (options = {}) {
|
||||||
? await this._getDocumentsAPI(mendeleyGroupID)
|
? await this._getDocumentsAPI(mendeleyGroupID)
|
||||||
: await this._getDocumentsDB(mendeleyGroupID);
|
: await this._getDocumentsDB(mendeleyGroupID);
|
||||||
|
|
||||||
this._progressMax = documents.length;
|
// Update progress to reflect items to import and remaining meta data stages
|
||||||
|
// We arbitrary set progress at approx 4%. We then add 8, one "tick" for each remaining meta data download.
|
||||||
|
this._progress = Math.max(Math.floor(0.04 * documents.length), 2);
|
||||||
|
this._progressMax = documents.length + this._progress + 8;
|
||||||
// Get various attributes mapped to document ids
|
// Get various attributes mapped to document ids
|
||||||
let urls = this._tokens
|
let urls = this._tokens
|
||||||
? await this._getDocumentURLsAPI(documents)
|
? await this._getDocumentURLsAPI(documents)
|
||||||
: await this._getDocumentURLsDB(mendeleyGroupID);
|
: await this._getDocumentURLsDB(mendeleyGroupID);
|
||||||
|
|
||||||
|
this._interruptChecker(true);
|
||||||
|
|
||||||
let creators = this._tokens
|
let creators = this._tokens
|
||||||
? await this._getDocumentCreatorsAPI(documents)
|
? await this._getDocumentCreatorsAPI(documents)
|
||||||
: await this._getDocumentCreatorsDB(mendeleyGroupID, map.creatorTypes);
|
: await this._getDocumentCreatorsDB(mendeleyGroupID, map.creatorTypes);
|
||||||
|
|
||||||
|
this._interruptChecker(true);
|
||||||
|
|
||||||
let tags = this._tokens
|
let tags = this._tokens
|
||||||
? await this._getDocumentTagsAPI(documents)
|
? await this._getDocumentTagsAPI(documents)
|
||||||
: await this._getDocumentTagsDB(mendeleyGroupID);
|
: await this._getDocumentTagsDB(mendeleyGroupID);
|
||||||
|
|
||||||
|
this._interruptChecker(true);
|
||||||
|
|
||||||
let collections = this._tokens
|
let collections = this._tokens
|
||||||
? await this._getDocumentCollectionsAPI(documents, rootCollectionKey, folderKeys)
|
? await this._getDocumentCollectionsAPI(documents, rootCollectionKey, folderKeys)
|
||||||
: await this._getDocumentCollectionsDB(mendeleyGroupID, documents, rootCollectionKey, folderKeys);
|
: await this._getDocumentCollectionsDB(mendeleyGroupID, documents, rootCollectionKey, folderKeys);
|
||||||
|
|
||||||
|
this._interruptChecker(true);
|
||||||
|
|
||||||
let files = this._tokens
|
let files = this._tokens
|
||||||
? await this._getDocumentFilesAPI(documents)
|
? await this._getDocumentFilesAPI(documents)
|
||||||
: await this._getDocumentFilesDB(mendeleyGroupID);
|
: await this._getDocumentFilesDB(mendeleyGroupID);
|
||||||
|
|
||||||
|
this._interruptChecker(true);
|
||||||
|
|
||||||
let annotations = this._tokens
|
let annotations = this._tokens
|
||||||
? await this._getDocumentAnnotationsAPI(mendeleyGroupID)
|
? await this._getDocumentAnnotationsAPI(mendeleyGroupID)
|
||||||
: await this._getDocumentAnnotationsDB(mendeleyGroupID);
|
: await this._getDocumentAnnotationsDB(mendeleyGroupID);
|
||||||
|
|
||||||
|
this._interruptChecker(true);
|
||||||
|
|
||||||
let profile = this._tokens
|
let profile = this._tokens
|
||||||
? await this._getProfileAPI()
|
? await this._getProfileAPI()
|
||||||
: await this._getProfileDB();
|
: await this._getProfileDB();
|
||||||
|
|
||||||
|
this._interruptChecker(true);
|
||||||
|
|
||||||
let groups = this._tokens
|
let groups = this._tokens
|
||||||
? await this._getGroupsAPI()
|
? await this._getGroupsAPI()
|
||||||
: await this._getGroupsDB();
|
: await this._getGroupsDB();
|
||||||
|
|
||||||
|
this._interruptChecker(true);
|
||||||
|
|
||||||
const fileHashLookup = new Map();
|
const fileHashLookup = new Map();
|
||||||
|
|
||||||
for (let [documentID, fileEntries] of files) {
|
for (let [documentID, fileEntries] of files) {
|
||||||
|
|
@ -165,7 +207,6 @@ Zotero_Import_Mendeley.prototype.translate = async function (options = {}) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (let group of groups) {
|
for (let group of groups) {
|
||||||
let groupAnnotations = this._tokens
|
let groupAnnotations = this._tokens
|
||||||
? await this._getDocumentAnnotationsAPI(group.id, profile.id)
|
? await this._getDocumentAnnotationsAPI(group.id, profile.id)
|
||||||
|
|
@ -263,11 +304,12 @@ Zotero_Import_Mendeley.prototype.translate = async function (options = {}) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
this.newItems.push(Zotero.Items.get(documentIDMap.get(document.id)));
|
this.newItems.push(Zotero.Items.get(documentIDMap.get(document.id)));
|
||||||
this._progress++;
|
this._interruptChecker(true);
|
||||||
if (this._itemDone) {
|
|
||||||
this._itemDone();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Zotero.debug(`Completed Mendeley import in ${Math.round((Date.now() - this._started) / 1000)}s. (Started: ${this._started})`);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
Zotero.logError(e);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
try {
|
try {
|
||||||
|
|
@ -275,6 +317,7 @@ Zotero_Import_Mendeley.prototype.translate = async function (options = {}) {
|
||||||
await this._db.closeDatabase();
|
await this._db.closeDatabase();
|
||||||
}
|
}
|
||||||
if (this._tokens) {
|
if (this._tokens) {
|
||||||
|
Zotero.debug(`Clearing ${this._tmpFilesToDelete.length} temporary files after Mendeley import`);
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
this._tmpFilesToDelete.map(f => this._removeTemporaryFile(f))
|
this._tmpFilesToDelete.map(f => this._removeTemporaryFile(f))
|
||||||
);
|
);
|
||||||
|
|
@ -288,14 +331,20 @@ Zotero_Import_Mendeley.prototype.translate = async function (options = {}) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Zotero_Import_Mendeley.prototype.interrupt = function () {
|
||||||
|
this._interrupted = true;
|
||||||
|
|
||||||
|
if (this._caller) {
|
||||||
|
this._caller.stop();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Zotero_Import_Mendeley.prototype._removeTemporaryFile = async function (file) {
|
Zotero_Import_Mendeley.prototype._removeTemporaryFile = async function (file) {
|
||||||
const containingDir = OS.Path.dirname(file);
|
|
||||||
try {
|
try {
|
||||||
await Zotero.File.removeIfExists(file);
|
await Zotero.File.removeIfExists(file);
|
||||||
await OS.File.removeEmptyDir(containingDir);
|
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
Zotero.logError(e);
|
Zotero.logError("Error while removing temporary file " + file + ": " + e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -345,7 +394,7 @@ Zotero_Import_Mendeley.prototype._getFoldersAPI = async function (groupID) {
|
||||||
if (groupID && groupID !== 0) {
|
if (groupID && groupID !== 0) {
|
||||||
params.group_id = groupID; //eslint-disable-line camelcase
|
params.group_id = groupID; //eslint-disable-line camelcase
|
||||||
}
|
}
|
||||||
return (await getAll(this._tokens, 'folders', params, headers)).map(f => ({
|
return (await getAll(this._tokens, 'folders', params, headers, {}, this._interruptChecker)).map(f => ({
|
||||||
id: f.id,
|
id: f.id,
|
||||||
uuid: f.id,
|
uuid: f.id,
|
||||||
name: f.name,
|
name: f.name,
|
||||||
|
|
@ -365,11 +414,11 @@ Zotero_Import_Mendeley.prototype._foldersToAPIJSON = function (folderRows, paren
|
||||||
};
|
};
|
||||||
|
|
||||||
Zotero_Import_Mendeley.prototype._getFolderDescendents = function (folderID, folderKey, folderRows, maxDepth) {
|
Zotero_Import_Mendeley.prototype._getFolderDescendents = function (folderID, folderKey, folderRows, maxDepth) {
|
||||||
if (maxDepth == 0) return []
|
if (maxDepth == 0) return [];
|
||||||
var descendents = [];
|
var descendents = [];
|
||||||
var children = folderRows
|
var children = folderRows
|
||||||
.filter(f => f.parentId == folderID)
|
.filter(f => f.parentId == folderID)
|
||||||
.map(f => {
|
.map((f) => {
|
||||||
let c = {
|
let c = {
|
||||||
folderID: f.id,
|
folderID: f.id,
|
||||||
remoteUUID: f.remoteUuid,
|
remoteUUID: f.remoteUuid,
|
||||||
|
|
@ -492,7 +541,7 @@ Zotero_Import_Mendeley.prototype._getDocumentsAPI = async function (groupID) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return (await getAll(this._tokens, 'documents', params, headers)).map(d => ({
|
return (await getAll(this._tokens, 'documents', params, headers, {}, this._interruptChecker)).map(d => ({
|
||||||
...d,
|
...d,
|
||||||
uuid: d.id,
|
uuid: d.id,
|
||||||
remoteUuid: d.id
|
remoteUuid: d.id
|
||||||
|
|
@ -693,12 +742,13 @@ Zotero_Import_Mendeley.prototype._fetchFile = async function (fileID, filePath)
|
||||||
Zotero_Import_Mendeley.prototype._getDocumentFilesAPI = async function (documents) {
|
Zotero_Import_Mendeley.prototype._getDocumentFilesAPI = async function (documents) {
|
||||||
const map = new Map();
|
const map = new Map();
|
||||||
|
|
||||||
let totalSize = 0;
|
this._totalSize = 0;
|
||||||
|
|
||||||
Components.utils.import("resource://zotero/concurrentCaller.js");
|
Components.utils.import("resource://zotero/concurrentCaller.js");
|
||||||
var caller = new ConcurrentCaller({
|
this._caller = new ConcurrentCaller({
|
||||||
numConcurrent: 6,
|
numConcurrent: 6,
|
||||||
onError: e => Zotero.logError(e),
|
onError: e => Zotero.logError(e),
|
||||||
|
logger: Zotero.debug,
|
||||||
Promise: Zotero.Promise
|
Promise: Zotero.Promise
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -712,7 +762,7 @@ Zotero_Import_Mendeley.prototype._getDocumentFilesAPI = async function (document
|
||||||
let tmpFile = OS.Path.join(Zotero.getTempDirectory().path, `m-api-${file.id}.${ext}`);
|
let tmpFile = OS.Path.join(Zotero.getTempDirectory().path, `m-api-${file.id}.${ext}`);
|
||||||
|
|
||||||
this._tmpFilesToDelete.push(tmpFile);
|
this._tmpFilesToDelete.push(tmpFile);
|
||||||
caller.add(this._fetchFile.bind(this, file.id, tmpFile));
|
this._caller.add(this._fetchFile.bind(this, file.id, tmpFile));
|
||||||
files.push({
|
files.push({
|
||||||
fileURL: OS.Path.toFileURI(tmpFile),
|
fileURL: OS.Path.toFileURI(tmpFile),
|
||||||
title: file.file_name || '',
|
title: file.file_name || '',
|
||||||
|
|
@ -720,13 +770,14 @@ Zotero_Import_Mendeley.prototype._getDocumentFilesAPI = async function (document
|
||||||
hash: file.filehash,
|
hash: file.filehash,
|
||||||
fileBaseName
|
fileBaseName
|
||||||
});
|
});
|
||||||
totalSize += file.size;
|
this._totalSize += file.size;
|
||||||
this._progressMax += 1;
|
this._progressMax += 1;
|
||||||
}
|
}
|
||||||
map.set(doc.id, files);
|
map.set(doc.id, files);
|
||||||
}
|
}
|
||||||
// TODO: check if enough space available totalSize
|
// TODO: check if enough space available totalSize
|
||||||
await caller.runAll();
|
await this._caller.runAll();
|
||||||
|
this._caller = null;
|
||||||
return map;
|
return map;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -823,7 +874,7 @@ Zotero_Import_Mendeley.prototype._getDocumentAnnotationsAPI = async function (gr
|
||||||
}
|
}
|
||||||
|
|
||||||
const map = new Map();
|
const map = new Map();
|
||||||
(await getAll(this._tokens, 'annotations', params, { Accept: 'application/vnd.mendeley-annotation.1+json' }))
|
(await getAll(this._tokens, 'annotations', params, { Accept: 'application/vnd.mendeley-annotation.1+json' }, {}, this._interruptChecker))
|
||||||
.forEach((a) => {
|
.forEach((a) => {
|
||||||
if (profileID !== null && a.profile_id !== profileID) {
|
if (profileID !== null && a.profile_id !== profileID) {
|
||||||
// optionally filter annotations by profile id
|
// optionally filter annotations by profile id
|
||||||
|
|
@ -885,7 +936,7 @@ Zotero_Import_Mendeley.prototype._getGroupsAPI = async function () {
|
||||||
const params = { type: 'all' };
|
const params = { type: 'all' };
|
||||||
const headers = { Accept: 'application/vnd.mendeley-group-list+json' };
|
const headers = { Accept: 'application/vnd.mendeley-group-list+json' };
|
||||||
|
|
||||||
return getAll(this._tokens, 'groups/v2', params, headers);
|
return getAll(this._tokens, 'groups/v2', params, headers, {}, this._interruptChecker);
|
||||||
};
|
};
|
||||||
|
|
||||||
Zotero_Import_Mendeley.prototype._getGroupsDB = async function () {
|
Zotero_Import_Mendeley.prototype._getGroupsDB = async function () {
|
||||||
|
|
@ -985,14 +1036,14 @@ Zotero_Import_Mendeley.prototype._documentToAPIJSON = async function (map, docum
|
||||||
|
|
||||||
for (let field in parent) {
|
for (let field in parent) {
|
||||||
switch (field) {
|
switch (field) {
|
||||||
case 'itemType':
|
case 'itemType':
|
||||||
case 'key':
|
case 'key':
|
||||||
case 'parentItem':
|
case 'parentItem':
|
||||||
case 'note':
|
case 'note':
|
||||||
case 'creators':
|
case 'creators':
|
||||||
case 'dateAdded':
|
case 'dateAdded':
|
||||||
case 'dateModified':
|
case 'dateModified':
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move unknown/invalid fields to Extra
|
// Move unknown/invalid fields to Extra
|
||||||
|
|
@ -1035,7 +1086,7 @@ Zotero_Import_Mendeley.prototype._documentToAPIJSON = async function (map, docum
|
||||||
// seriesEditor isn't valid on some item types (e.g., book)
|
// seriesEditor isn't valid on some item types (e.g., book)
|
||||||
if (creator.creatorType == 'seriesEditor'
|
if (creator.creatorType == 'seriesEditor'
|
||||||
&& !Zotero.CreatorTypes.isValidForItemType(
|
&& !Zotero.CreatorTypes.isValidForItemType(
|
||||||
Zotero.CreatorTypes.getID('seriesEditor'), itemTypeID)) {
|
Zotero.CreatorTypes.getID('seriesEditor'), itemTypeID)) {
|
||||||
creator.creatorType = 'editor';
|
creator.creatorType = 'editor';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1160,7 +1211,6 @@ Zotero_Import_Mendeley.prototype._processField = function (parent, children, zFi
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Zotero.warn(`Unknown function subfield: ${subfield}`);
|
Zotero.warn(`Unknown function subfield: ${subfield}`);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
@ -1191,20 +1241,21 @@ Zotero_Import_Mendeley.prototype._makeCreator = function (creatorType, firstName
|
||||||
Zotero_Import_Mendeley.prototype._addExtraField = function (extra, field, val) {
|
Zotero_Import_Mendeley.prototype._addExtraField = function (extra, field, val) {
|
||||||
// Strip the field if it appears at the beginning of the value (to avoid "DOI: DOI: 10...")
|
// Strip the field if it appears at the beginning of the value (to avoid "DOI: DOI: 10...")
|
||||||
if (typeof val == 'string') {
|
if (typeof val == 'string') {
|
||||||
val = val.replace(new RegExp(`^${field}:\s*`, 'i'), "");
|
val = val.replace(new RegExp(`^${field}:\\s*`, 'i'), "");
|
||||||
}
|
}
|
||||||
extra = extra ? extra + '\n' : '';
|
extra = extra ? extra + '\n' : '';
|
||||||
if (field != 'arXiv') {
|
if (field != 'arXiv') {
|
||||||
field = field[0].toUpperCase() + field.substr(1);
|
field = field[0].toUpperCase() + field.substr(1);
|
||||||
field = field.replace(/([a-z])([A-Z][a-z])/, "$1 $2");
|
field = field.replace(/([a-z])([A-Z][a-z])/, "$1 $2");
|
||||||
}
|
}
|
||||||
|
|
||||||
return extra + `${field}: ${val}`;
|
return extra + `${field}: ${val}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
Zotero_Import_Mendeley.prototype._convertNote = function (note) {
|
Zotero_Import_Mendeley.prototype._convertNote = function (note) {
|
||||||
return note
|
return note
|
||||||
// Add newlines after <br>
|
// Add newlines after <br>
|
||||||
.replace(/<br\s*\/>/g, '<br\/>\n')
|
.replace(/<br\s*\/>/g, '<br/>\n')
|
||||||
//
|
//
|
||||||
// Legacy pre-HTML stuff
|
// Legacy pre-HTML stuff
|
||||||
//
|
//
|
||||||
|
|
@ -1360,7 +1411,7 @@ Zotero_Import_Mendeley.prototype._findExistingItem = async function (libraryID,
|
||||||
Zotero.debug(`Found existing item ${existingItem.libraryKey} for `
|
Zotero.debug(`Found existing item ${existingItem.libraryKey} for `
|
||||||
+ `${predicate} ${itemJSON.relations[predicate]}`);
|
+ `${predicate} ${itemJSON.relations[predicate]}`);
|
||||||
return existingItem;
|
return existingItem;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
Zotero_Import_Mendeley.prototype._getItemByRelation = async function (libraryID, predicate, object) {
|
Zotero_Import_Mendeley.prototype._getItemByRelation = async function (libraryID, predicate, object) {
|
||||||
|
|
@ -1443,7 +1494,7 @@ Zotero_Import_Mendeley.prototype._saveFilesAndAnnotations = async function (file
|
||||||
Zotero.logError(e);
|
Zotero.logError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
Zotero_Import_Mendeley.prototype._findExistingFile = function (parentItemID, file) {
|
Zotero_Import_Mendeley.prototype._findExistingFile = function (parentItemID, file) {
|
||||||
|
|
@ -1460,7 +1511,7 @@ Zotero_Import_Mendeley.prototype._findExistingFile = function (parentItemID, fil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
};
|
||||||
|
|
||||||
Zotero_Import_Mendeley.prototype._isDownloadedFile = function (path) {
|
Zotero_Import_Mendeley.prototype._isDownloadedFile = function (path) {
|
||||||
var parentDir = OS.Path.dirname(path);
|
var parentDir = OS.Path.dirname(path);
|
||||||
|
|
@ -1468,7 +1519,7 @@ Zotero_Import_Mendeley.prototype._isDownloadedFile = function (path) {
|
||||||
|| parentDir.endsWith(OS.Path.join('Local', 'Mendeley Ltd', 'Mendeley Desktop', 'Downloaded'))
|
|| parentDir.endsWith(OS.Path.join('Local', 'Mendeley Ltd', 'Mendeley Desktop', 'Downloaded'))
|
||||||
|| parentDir.endsWith(OS.Path.join('Local', 'Mendeley Ltd.', 'Mendeley Desktop', 'Downloaded'))
|
|| parentDir.endsWith(OS.Path.join('Local', 'Mendeley Ltd.', 'Mendeley Desktop', 'Downloaded'))
|
||||||
|| parentDir.endsWith(OS.Path.join('data', 'Mendeley Ltd.', 'Mendeley Desktop', 'Downloaded'));
|
|| parentDir.endsWith(OS.Path.join('data', 'Mendeley Ltd.', 'Mendeley Desktop', 'Downloaded'));
|
||||||
}
|
};
|
||||||
|
|
||||||
Zotero_Import_Mendeley.prototype._isTempDownloadedFile = function (path) {
|
Zotero_Import_Mendeley.prototype._isTempDownloadedFile = function (path) {
|
||||||
return path.startsWith(OS.Path.join(Zotero.getTempDirectory().path, 'm-api'));
|
return path.startsWith(OS.Path.join(Zotero.getTempDirectory().path, 'm-api'));
|
||||||
|
|
@ -1498,7 +1549,7 @@ Zotero_Import_Mendeley.prototype._getRealFilePath = async function (path) {
|
||||||
return altPath;
|
return altPath;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
};
|
||||||
|
|
||||||
Zotero_Import_Mendeley.prototype._saveAnnotations = async function (annotations, parentItemID, attachmentItemID, fileHash) {
|
Zotero_Import_Mendeley.prototype._saveAnnotations = async function (annotations, parentItemID, attachmentItemID, fileHash) {
|
||||||
if (!annotations.length) return;
|
if (!annotations.length) return;
|
||||||
|
|
@ -1507,7 +1558,6 @@ Zotero_Import_Mendeley.prototype._saveAnnotations = async function (annotations,
|
||||||
var libraryID = parentItem.libraryID;
|
var libraryID = parentItem.libraryID;
|
||||||
if (attachmentItemID) {
|
if (attachmentItemID) {
|
||||||
var attachmentItem = Zotero.Items.get(attachmentItemID);
|
var attachmentItem = Zotero.Items.get(attachmentItemID);
|
||||||
var attachmentURIPath = Zotero.API.getLibraryPrefix(libraryID) + '/items/' + attachmentItem.key;
|
|
||||||
|
|
||||||
if (attachmentItem) {
|
if (attachmentItem) {
|
||||||
let file = await attachmentItem.getFilePathAsync();
|
let file = await attachmentItem.getFilePathAsync();
|
||||||
|
|
@ -1530,6 +1580,10 @@ Zotero_Import_Mendeley.prototype._saveAnnotations = async function (annotations,
|
||||||
}
|
}
|
||||||
// PDFWorker needs 'id'
|
// PDFWorker needs 'id'
|
||||||
annotations.forEach(annotation => annotation.id = annotation.uuid);
|
annotations.forEach(annotation => annotation.id = annotation.uuid);
|
||||||
|
annotations.forEach(annotation => (colorMap.has(annotation.color)
|
||||||
|
? annotation.color = colorMap.get(annotation.color)
|
||||||
|
: annotation.color
|
||||||
|
));
|
||||||
// Returns 'id', 'position', 'type', 'pageLabel', 'sortIndex', 'text' (for highlight)
|
// Returns 'id', 'position', 'type', 'pageLabel', 'sortIndex', 'text' (for highlight)
|
||||||
Zotero.debug("Processing annotations in " + file);
|
Zotero.debug("Processing annotations in " + file);
|
||||||
annotations = await Zotero.PDFWorker.processMendeleyAnnotations(file, annotations);
|
annotations = await Zotero.PDFWorker.processMendeleyAnnotations(file, annotations);
|
||||||
|
|
@ -1616,7 +1670,7 @@ Zotero_Import_Mendeley.prototype._saveAnnotations = async function (annotations,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
note.setNote('<h1>' + Zotero.getString('extractedAnnotations') + '</h1>\n' + noteStrings.join('\n'));
|
note.setNote('<h1>' + Zotero.getString('extractedAnnotations') + '</h1>\n' + noteStrings.join('\n'));
|
||||||
return note.saveTx(this._saveOptions);
|
await note.saveTx(this._saveOptions);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1633,17 +1687,7 @@ Zotero_Import_Mendeley.prototype._updateParentKeys = function (objectType, json,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
Zotero_Import_Mendeley.prototype._updateItemCollectionKeys = function (json, oldKey, newKey) {
|
|
||||||
for (; i < json.length; i++) {
|
|
||||||
let x = json[i];
|
|
||||||
if (x[prop] == oldKey) {
|
|
||||||
x[prop] = newKey;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Clean up extra files created <5.0.51
|
// Clean up extra files created <5.0.51
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
var map = {
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
var mendeleyDBMaps = {
|
||||||
83: {
|
83: {
|
||||||
itemTypes: {
|
itemTypes: {
|
||||||
Bill: "bill",
|
Bill: "bill",
|
||||||
|
|
|
||||||
|
|
@ -113,9 +113,10 @@ var Zotero_Citation_Dialog = new function () {
|
||||||
var menu = document.getElementById("label");
|
var menu = document.getElementById("label");
|
||||||
var label_list = document.getElementById("locator-type-popup");
|
var label_list = document.getElementById("locator-type-popup");
|
||||||
var i = 0;
|
var i = 0;
|
||||||
|
var pageLocatorIndex;
|
||||||
for(var value in locators) {
|
for(var value in locators) {
|
||||||
var locator = locators[value];
|
var locator = locators[value];
|
||||||
var locatorLabel = Zotero.getString('citation.locator.'+locator.replace(/\s/g,''));
|
let locatorLabel = Zotero.Cite.getLocatorString(locator);
|
||||||
// add to list of labels
|
// add to list of labels
|
||||||
var child = document.createElement("menuitem");
|
var child = document.createElement("menuitem");
|
||||||
child.setAttribute("value", value);
|
child.setAttribute("value", value);
|
||||||
|
|
@ -124,9 +125,13 @@ var Zotero_Citation_Dialog = new function () {
|
||||||
// add to array
|
// add to array
|
||||||
_locatorIndexArray[locator] = i;
|
_locatorIndexArray[locator] = i;
|
||||||
_locatorNameArray[i] = locator;
|
_locatorNameArray[i] = locator;
|
||||||
|
if (locator == 'page') {
|
||||||
|
pageLocatorIndex = i;
|
||||||
|
_preserveData.label[1] = i;
|
||||||
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
menu.selectedIndex = 0;
|
menu.selectedIndex = pageLocatorIndex;
|
||||||
|
|
||||||
// load (from selectItemsDialog.js)
|
// load (from selectItemsDialog.js)
|
||||||
yield doLoad();
|
yield doLoad();
|
||||||
|
|
|
||||||
|
|
@ -116,10 +116,9 @@ var Zotero_QuickFormat = new function () {
|
||||||
|
|
||||||
// add labels to popup
|
// add labels to popup
|
||||||
var locators = Zotero.Cite.labels;
|
var locators = Zotero.Cite.labels;
|
||||||
var menu = document.getElementById("locator-label");
|
|
||||||
var labelList = document.getElementById("locator-label-popup");
|
var labelList = document.getElementById("locator-label-popup");
|
||||||
for(var locator of locators) {
|
for(var locator of locators) {
|
||||||
var locatorLabel = Zotero.getString('citation.locator.'+locator.replace(/\s/g,''));
|
let locatorLabel = Zotero.Cite.getLocatorString(locator);
|
||||||
|
|
||||||
// add to list of labels
|
// add to list of labels
|
||||||
var child = document.createElement("menuitem");
|
var child = document.createElement("menuitem");
|
||||||
|
|
@ -127,7 +126,6 @@ var Zotero_QuickFormat = new function () {
|
||||||
child.setAttribute("label", locatorLabel);
|
child.setAttribute("label", locatorLabel);
|
||||||
labelList.appendChild(child);
|
labelList.appendChild(child);
|
||||||
}
|
}
|
||||||
menu.selectedIndex = 0;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -729,9 +727,7 @@ var Zotero_QuickFormat = new function () {
|
||||||
|
|
||||||
// Title, if no creator (getDisplayTitle in order to get case, e-mail, statute which don't have a title field)
|
// Title, if no creator (getDisplayTitle in order to get case, e-mail, statute which don't have a title field)
|
||||||
title = item.getDisplayTitle();
|
title = item.getDisplayTitle();
|
||||||
if (item.isNote()) {
|
title = title.substr(0, 32) + (title.length > 32 ? "…" : "");
|
||||||
title = title.substr(0, 24) + '…';
|
|
||||||
}
|
|
||||||
if (!str) {
|
if (!str) {
|
||||||
str = Zotero.getString("punctuation.openingQMark") + title + Zotero.getString("punctuation.closingQMark");
|
str = Zotero.getString("punctuation.openingQMark") + title + Zotero.getString("punctuation.closingQMark");
|
||||||
}
|
}
|
||||||
|
|
@ -758,15 +754,17 @@ var Zotero_QuickFormat = new function () {
|
||||||
|
|
||||||
// Prefix
|
// Prefix
|
||||||
if(citationItem.prefix && Zotero.CiteProc.CSL.ENDSWITH_ROMANESQUE_REGEXP) {
|
if(citationItem.prefix && Zotero.CiteProc.CSL.ENDSWITH_ROMANESQUE_REGEXP) {
|
||||||
str = citationItem.prefix
|
let prefix = citationItem.prefix.substr(0, 10) + (citationItem.prefix.length > 10 ? "…" : "")
|
||||||
|
str = prefix
|
||||||
+(Zotero.CiteProc.CSL.ENDSWITH_ROMANESQUE_REGEXP.test(citationItem.prefix) ? " " : "")
|
+(Zotero.CiteProc.CSL.ENDSWITH_ROMANESQUE_REGEXP.test(citationItem.prefix) ? " " : "")
|
||||||
+str;
|
+str;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Suffix
|
// Suffix
|
||||||
if(citationItem.suffix && Zotero.CiteProc.CSL.STARTSWITH_ROMANESQUE_REGEXP) {
|
if(citationItem.suffix && Zotero.CiteProc.CSL.STARTSWITH_ROMANESQUE_REGEXP) {
|
||||||
|
let suffix = citationItem.suffix.substr(0, 10) + (citationItem.suffix.length > 10 ? "…" : "")
|
||||||
str += (Zotero.CiteProc.CSL.STARTSWITH_ROMANESQUE_REGEXP.test(citationItem.suffix) ? " " : "")
|
str += (Zotero.CiteProc.CSL.STARTSWITH_ROMANESQUE_REGEXP.test(citationItem.suffix) ? " " : "")
|
||||||
+citationItem.suffix;
|
+ suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
|
|
@ -778,9 +776,6 @@ var Zotero_QuickFormat = new function () {
|
||||||
function _insertBubble(citationItem, nextNode) {
|
function _insertBubble(citationItem, nextNode) {
|
||||||
var str = _buildBubbleString(citationItem);
|
var str = _buildBubbleString(citationItem);
|
||||||
|
|
||||||
// It's entirely unintuitive why, but after trying a bunch of things, it looks like using
|
|
||||||
// a XUL label for these things works best. A regular span causes issues with moving the
|
|
||||||
// cursor.
|
|
||||||
var bubble = qfiDocument.createElement("span");
|
var bubble = qfiDocument.createElement("span");
|
||||||
bubble.setAttribute("class", "citation-dialog bubble");
|
bubble.setAttribute("class", "citation-dialog bubble");
|
||||||
bubble.setAttribute("draggable", "true");
|
bubble.setAttribute("draggable", "true");
|
||||||
|
|
@ -1085,15 +1080,16 @@ var Zotero_QuickFormat = new function () {
|
||||||
let citationItem = JSON.parse(target.dataset.citationItem);
|
let citationItem = JSON.parse(target.dataset.citationItem);
|
||||||
panelPrefix.value = citationItem["prefix"] ? citationItem["prefix"] : "";
|
panelPrefix.value = citationItem["prefix"] ? citationItem["prefix"] : "";
|
||||||
panelSuffix.value = citationItem["suffix"] ? citationItem["suffix"] : "";
|
panelSuffix.value = citationItem["suffix"] ? citationItem["suffix"] : "";
|
||||||
|
var pageOption = panelLocatorLabel.getElementsByAttribute("value", "page")[0];
|
||||||
if(citationItem["label"]) {
|
if(citationItem["label"]) {
|
||||||
var option = panelLocatorLabel.getElementsByAttribute("value", citationItem["label"]);
|
var option = panelLocatorLabel.getElementsByAttribute("value", citationItem["label"]);
|
||||||
if(option.length) {
|
if(option.length) {
|
||||||
panelLocatorLabel.selectedItem = option[0];
|
panelLocatorLabel.selectedItem = option[0];
|
||||||
} else {
|
} else {
|
||||||
panelLocatorLabel.selectedIndex = 0;
|
panelLocatorLabel.selectedItem = pageOption;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
panelLocatorLabel.selectedIndex = 0;
|
panelLocatorLabel.selectedItem = pageOption;
|
||||||
}
|
}
|
||||||
panelLocator.value = citationItem["locator"] ? citationItem["locator"] : "";
|
panelLocator.value = citationItem["locator"] ? citationItem["locator"] : "";
|
||||||
panelSuppressAuthor.checked = !!citationItem["suppress-author"];
|
panelSuppressAuthor.checked = !!citationItem["suppress-author"];
|
||||||
|
|
|
||||||
|
|
@ -38,9 +38,8 @@ const { Cc, Ci, Cu } = require('chrome');
|
||||||
Cu.import("resource://gre/modules/osfile.jsm");
|
Cu.import("resource://gre/modules/osfile.jsm");
|
||||||
|
|
||||||
const CHILD_INDENT = 12;
|
const CHILD_INDENT = 12;
|
||||||
const COLORED_TAGS_RE = new RegExp("^[0-" + Zotero.Tags.MAX_COLORED_TAGS + "]{1}$");
|
const COLORED_TAGS_RE = new RegExp("^(?:Numpad|Digit)([0-" + Zotero.Tags.MAX_COLORED_TAGS + "]{1})$");
|
||||||
const COLUMN_PREFS_FILEPATH = OS.Path.join(Zotero.Profile.dir, "treePrefs.json");
|
const COLUMN_PREFS_FILEPATH = OS.Path.join(Zotero.Profile.dir, "treePrefs.json");
|
||||||
const EMOJI_RE = /\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F/gu;
|
|
||||||
const HTML_NS = "http://www.w3.org/1999/xhtml";
|
const HTML_NS = "http://www.w3.org/1999/xhtml";
|
||||||
const ATTACHMENT_STATE_LOAD_DELAY = 150; //ms
|
const ATTACHMENT_STATE_LOAD_DELAY = 150; //ms
|
||||||
|
|
||||||
|
|
@ -448,11 +447,20 @@ var ItemTree = class ItemTree extends LibraryTree {
|
||||||
let row = this.getRowIndexByID(id);
|
let row = this.getRowIndexByID(id);
|
||||||
if (row === false) continue;
|
if (row === false) continue;
|
||||||
let item = Zotero.Items.get(id);
|
let item = Zotero.Items.get(id);
|
||||||
if (!item.deleted && !item.numChildren()) {
|
// Remove parent row if it isn't deleted and doesn't have any deleted children
|
||||||
|
// (shown by the numChildren including deleted being the same as numChildren not including deleted)
|
||||||
|
if (!item.deleted && (!item.isRegularItem() || item.numChildren(true) == item.numChildren(false))) {
|
||||||
rows.push(row);
|
rows.push(row);
|
||||||
|
// And all its children in the tree
|
||||||
|
for (let child = row + 1; child < this.rowCount && this.getLevel(child) > this.getLevel(row); child++) {
|
||||||
|
rows.push(child);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this._removeRows(rows);
|
if (rows.length) {
|
||||||
|
this._removeRows(rows);
|
||||||
|
this.tree.invalidate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
@ -475,14 +483,17 @@ var ItemTree = class ItemTree extends LibraryTree {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var visibleSubcollections = Zotero.Prefs.get('recursiveCollections')
|
||||||
|
? collectionTreeRow.ref.getDescendents(false, 'collection')
|
||||||
|
: [];
|
||||||
var splitIDs = [];
|
var splitIDs = [];
|
||||||
for (let id of ids) {
|
for (let id of ids) {
|
||||||
var split = id.split('-');
|
var split = id.split('-');
|
||||||
// Skip if not an item in this collection
|
// Include if an item in this collection or a visible subcollection
|
||||||
if (split[0] != collectionTreeRow.ref.id) {
|
if (split[0] == collectionTreeRow.ref.id
|
||||||
continue;
|
|| visibleSubcollections.some(c => split[0] == c.id)) {
|
||||||
|
splitIDs.push(split[1]);
|
||||||
}
|
}
|
||||||
splitIDs.push(split[1]);
|
|
||||||
}
|
}
|
||||||
ids = splitIDs;
|
ids = splitIDs;
|
||||||
}
|
}
|
||||||
|
|
@ -859,9 +870,9 @@ var ItemTree = class ItemTree extends LibraryTree {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!event.shiftKey && !event.ctrlKey && !event.metaKey && !event.altKey && COLORED_TAGS_RE.test(event.key)) {
|
if (!event.shiftKey && !event.ctrlKey && !event.metaKey && !event.altKey && COLORED_TAGS_RE.test(event.code)) {
|
||||||
let libraryID = this.collectionTreeRow.ref.libraryID;
|
let libraryID = this.collectionTreeRow.ref.libraryID;
|
||||||
let position = parseInt(event.key) - 1;
|
let position = COLORED_TAGS_RE.exec(event.code)[1] - 1;
|
||||||
// When 0 is pressed, remove all colored tags
|
// When 0 is pressed, remove all colored tags
|
||||||
if (position == -1) {
|
if (position == -1) {
|
||||||
let items = this.getSelectedItems();
|
let items = this.getSelectedItems();
|
||||||
|
|
@ -978,7 +989,7 @@ var ItemTree = class ItemTree extends LibraryTree {
|
||||||
|
|
||||||
onItemContextMenu: (...args) => this.props.onContextMenu(...args),
|
onItemContextMenu: (...args) => this.props.onContextMenu(...args),
|
||||||
|
|
||||||
role: 'treegrid',
|
role: 'tree',
|
||||||
label: Zotero.getString('pane.items.title'),
|
label: Zotero.getString('pane.items.title'),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
@ -1241,20 +1252,14 @@ var ItemTree = class ItemTree extends LibraryTree {
|
||||||
? `for ${itemIDs.length} ` + Zotero.Utilities.pluralize(itemIDs.length, ['item', 'items'])
|
? `for ${itemIDs.length} ` + Zotero.Utilities.pluralize(itemIDs.length, ['item', 'items'])
|
||||||
: ""));
|
: ""));
|
||||||
|
|
||||||
// Set whether rows with empty values should be displayed last,
|
// Set whether rows with empty values should sort at the beginning
|
||||||
// which may be different for primary and secondary sorting.
|
var emptyFirst = {
|
||||||
var emptyFirst = {};
|
title: true,
|
||||||
switch (primaryField) {
|
|
||||||
case 'title':
|
|
||||||
emptyFirst.title = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
// When sorting by title we want empty titles at the top, but if not
|
// Date columns start descending, so put empty rows at end
|
||||||
// sorting by title, empty titles should sort to the bottom so that new
|
date: true,
|
||||||
// empty items don't get sorted to the middle of the items list.
|
year: true,
|
||||||
default:
|
};
|
||||||
emptyFirst.title = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cache primary values while sorting, since base-field-mapped getField()
|
// Cache primary values while sorting, since base-field-mapped getField()
|
||||||
// calls are relatively expensive
|
// calls are relatively expensive
|
||||||
|
|
@ -1262,7 +1267,7 @@ var ItemTree = class ItemTree extends LibraryTree {
|
||||||
sortFields.forEach(x => cache[x] = {});
|
sortFields.forEach(x => cache[x] = {});
|
||||||
|
|
||||||
// Get the display field for a row (which might be a placeholder title)
|
// Get the display field for a row (which might be a placeholder title)
|
||||||
function getField(field, row) {
|
let getField = (field, row) => {
|
||||||
var item = row.ref;
|
var item = row.ref;
|
||||||
|
|
||||||
switch (field) {
|
switch (field) {
|
||||||
|
|
@ -1270,23 +1275,12 @@ var ItemTree = class ItemTree extends LibraryTree {
|
||||||
return Zotero.Items.getSortTitle(item.getDisplayTitle());
|
return Zotero.Items.getSortTitle(item.getDisplayTitle());
|
||||||
|
|
||||||
case 'hasAttachment':
|
case 'hasAttachment':
|
||||||
if (item.isFileAttachment()) {
|
if (this._canGetBestAttachmentState(item)) {
|
||||||
var state = item.fileExistsCached() ? 1 : -1;
|
return item.getBestAttachmentStateCached();
|
||||||
}
|
|
||||||
else if (item.isRegularItem()) {
|
|
||||||
var state = item.getBestAttachmentStateCached();
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// Make sort order present, missing, empty when ascending
|
|
||||||
if (state === 1) {
|
|
||||||
state = 2;
|
|
||||||
}
|
|
||||||
else if (state === -1) {
|
|
||||||
state = 1;
|
|
||||||
}
|
|
||||||
return state;
|
|
||||||
|
|
||||||
case 'numNotes':
|
case 'numNotes':
|
||||||
return row.numNotes(false, true) || 0;
|
return row.numNotes(false, true) || 0;
|
||||||
|
|
@ -1350,7 +1344,11 @@ var ItemTree = class ItemTree extends LibraryTree {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sortField == 'hasAttachment') {
|
if (sortField == 'hasAttachment') {
|
||||||
return fieldB - fieldA;
|
// PDFs at the top
|
||||||
|
const order = ['pdf', 'snapshot', 'other', 'none'];
|
||||||
|
fieldA = order.indexOf(fieldA.type || 'none') + (fieldA.exists ? 0 : 4);
|
||||||
|
fieldB = order.indexOf(fieldB.type || 'none') + (fieldB.exists ? 0 : 4);
|
||||||
|
return fieldA - fieldB;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sortField == 'callNumber') {
|
if (sortField == 'callNumber') {
|
||||||
|
|
@ -1439,18 +1437,27 @@ var ItemTree = class ItemTree extends LibraryTree {
|
||||||
var openItemIDs = this._saveOpenState(true);
|
var openItemIDs = this._saveOpenState(true);
|
||||||
|
|
||||||
// Sort specific items
|
// Sort specific items
|
||||||
if (itemIDs) {
|
try {
|
||||||
let idsToSort = new Set(itemIDs);
|
if (itemIDs) {
|
||||||
this._rows.sort((a, b) => {
|
let idsToSort = new Set(itemIDs);
|
||||||
// Don't re-sort existing items. This assumes a stable sort(), which is the case in Firefox
|
this._rows.sort((a, b) => {
|
||||||
// but not Chrome/v8.
|
// Don't re-sort existing items. This assumes a stable sort(), which is the case in Firefox
|
||||||
if (!idsToSort.has(a.ref.id) && !idsToSort.has(b.ref.id)) return 0;
|
// but not Chrome/v8.
|
||||||
return rowSort(a, b) * order;
|
if (!idsToSort.has(a.ref.id) && !idsToSort.has(b.ref.id)) return 0;
|
||||||
});
|
return rowSort(a, b) * order;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Full sort
|
||||||
|
else {
|
||||||
|
this._rows.sort((a, b) => rowSort(a, b) * order);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Full sort
|
catch (e) {
|
||||||
else {
|
Zotero.logError("Error sorting fields: " + e.message);
|
||||||
this._rows.sort((a, b) => rowSort(a, b) * order);
|
Zotero.debug(e, 1);
|
||||||
|
// Clear anything that might be contributing to the error
|
||||||
|
Zotero.Prefs.clear('secondarySort.' + this.getSortField());
|
||||||
|
Zotero.Prefs.clear('fallbackSort');
|
||||||
}
|
}
|
||||||
|
|
||||||
this._refreshRowMap();
|
this._refreshRowMap();
|
||||||
|
|
@ -1748,8 +1755,21 @@ var ItemTree = class ItemTree extends LibraryTree {
|
||||||
await Zotero.Items.trashTx(ids);
|
await Zotero.Items.trashTx(ids);
|
||||||
}
|
}
|
||||||
else if (collectionTreeRow.isCollection()) {
|
else if (collectionTreeRow.isCollection()) {
|
||||||
|
let collectionIDs = [collectionTreeRow.ref.id];
|
||||||
|
if (Zotero.Prefs.get('recursiveCollections')) {
|
||||||
|
collectionIDs.push(...collectionTreeRow.ref.getDescendents(false, 'collection').map(c => c.id));
|
||||||
|
}
|
||||||
|
|
||||||
await Zotero.DB.executeTransaction(async () => {
|
await Zotero.DB.executeTransaction(async () => {
|
||||||
await collectionTreeRow.ref.removeItems(ids);
|
for (let itemID of ids) {
|
||||||
|
let item = Zotero.Items.get(itemID);
|
||||||
|
for (let collectionID of collectionIDs) {
|
||||||
|
item.removeFromCollection(collectionID);
|
||||||
|
}
|
||||||
|
await item.save({
|
||||||
|
skipDateModifiedUpdate: true
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (collectionTreeRow.isPublications()) {
|
else if (collectionTreeRow.isPublications()) {
|
||||||
|
|
@ -1788,6 +1808,11 @@ var ItemTree = class ItemTree extends LibraryTree {
|
||||||
return this._rows.map(row => asIDs ? row.ref.id : row.ref);
|
return this._rows.map(row => asIDs ? row.ref.id : row.ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current sort order of the items list
|
||||||
|
*
|
||||||
|
* @return {Number} - -1 for descending, 1 for ascending
|
||||||
|
*/
|
||||||
getSortDirection(sortFields) {
|
getSortDirection(sortFields) {
|
||||||
sortFields = sortFields || this.getSortFields();
|
sortFields = sortFields || this.getSortFields();
|
||||||
if (this.collectionTreeRow.isFeed()) {
|
if (this.collectionTreeRow.isFeed()) {
|
||||||
|
|
@ -1987,8 +2012,8 @@ var ItemTree = class ItemTree extends LibraryTree {
|
||||||
// If exporting with virtual "Markdown + Rich Text" translator, call Note Markdown
|
// If exporting with virtual "Markdown + Rich Text" translator, call Note Markdown
|
||||||
// and Note HTML translators instead
|
// and Note HTML translators instead
|
||||||
if (format.id === Zotero.Translators.TRANSLATOR_ID_MARKDOWN_AND_RICH_TEXT) {
|
if (format.id === Zotero.Translators.TRANSLATOR_ID_MARKDOWN_AND_RICH_TEXT) {
|
||||||
let markdownFormat = { mode: 'export', id: Zotero.Translators.TRANSLATOR_ID_NOTE_MARKDOWN };
|
let markdownFormat = { mode: 'export', id: Zotero.Translators.TRANSLATOR_ID_NOTE_MARKDOWN, options: format.markdownOptions };
|
||||||
let htmlFormat = { mode: 'export', id: Zotero.Translators.TRANSLATOR_ID_NOTE_HTML };
|
let htmlFormat = { mode: 'export', id: Zotero.Translators.TRANSLATOR_ID_NOTE_HTML, options: format.htmlOptions };
|
||||||
Zotero.QuickCopy.getContentFromItems(items, markdownFormat, (obj, worked) => {
|
Zotero.QuickCopy.getContentFromItems(items, markdownFormat, (obj, worked) => {
|
||||||
if (!worked) {
|
if (!worked) {
|
||||||
Zotero.log(Zotero.getString('fileInterface.exportError'), 'warning');
|
Zotero.log(Zotero.getString('fileInterface.exportError'), 'warning');
|
||||||
|
|
@ -2752,93 +2777,60 @@ var ItemTree = class ItemTree extends LibraryTree {
|
||||||
|
|
||||||
// TEMP: For now, we use the blue bullet for all non-PDF attachments, but there's
|
// TEMP: For now, we use the blue bullet for all non-PDF attachments, but there's
|
||||||
// commented-out code for showing different icons for snapshots, files, and URL/DOI links
|
// commented-out code for showing different icons for snapshots, files, and URL/DOI links
|
||||||
if (this.isContainer(index)) {
|
if (this._canGetBestAttachmentState(item)) {
|
||||||
if (item.isRegularItem()) {
|
const { type, exists } = item.getBestAttachmentStateCached();
|
||||||
const { type, exists } = item.getBestAttachmentStateCached();
|
|
||||||
let icon = "";
|
|
||||||
let ariaLabel;
|
|
||||||
// If the item has a child attachment
|
|
||||||
if (type !== null && type != 'none') {
|
|
||||||
if (type == 'pdf') {
|
|
||||||
icon = getDOMElement('IconTreeitemAttachmentPDF');
|
|
||||||
ariaLabel = Zotero.getString('pane.item.attachments.hasPDF');
|
|
||||||
if (!exists) {
|
|
||||||
icon.classList.add('icon-missing-file');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (type == 'snapshot') {
|
|
||||||
//icon = getDOMElement('IconTreeitemAttachmentSnapshot');
|
|
||||||
icon = exists ? getDOMElement('IconBulletBlue') : getDOMElement('IconBulletBlueEmpty');
|
|
||||||
ariaLabel = Zotero.getString('pane.item.attachments.hasSnapshot');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//icon = getDOMElement('IconTreeitem');
|
|
||||||
icon = exists ? getDOMElement('IconBulletBlue') : getDOMElement('IconBulletBlueEmpty');
|
|
||||||
ariaLabel = Zotero.getString('pane.item.attachments.has');
|
|
||||||
}
|
|
||||||
icon.classList.add('cell-icon');
|
|
||||||
//if (!exists) {
|
|
||||||
// icon.classList.add('icon-missing-file');
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
//else if (type == 'none') {
|
|
||||||
// if (item.getField('url') || item.getField('DOI')) {
|
|
||||||
// icon = getDOMElement('IconLink');
|
|
||||||
// ariaLabel = Zotero.getString('pane.item.attachments.hasLink');
|
|
||||||
// icon.classList.add('cell-icon');
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
if (ariaLabel) {
|
|
||||||
icon.setAttribute('aria-label', ariaLabel + '.');
|
|
||||||
span.setAttribute('title', ariaLabel);
|
|
||||||
}
|
|
||||||
span.append(icon);
|
|
||||||
|
|
||||||
// Don't run this immediately since it might cause a db check and disk access
|
|
||||||
// but delay for some time and see if the item is still visible in the tree
|
|
||||||
// (i.e. if we haven't scrolled right past it)
|
|
||||||
setTimeout(() => {
|
|
||||||
if (!this.tree.rowIsVisible(index)) return;
|
|
||||||
item.getBestAttachmentState()
|
|
||||||
// Refresh cell when promise is fulfilled
|
|
||||||
.then(({ type: newType, exists: newExists }) => {
|
|
||||||
if (newType !== type || newExists !== exists) {
|
|
||||||
this.tree.invalidateRow(index);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, ATTACHMENT_STATE_LOAD_DELAY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.isFileAttachment()) {
|
|
||||||
const exists = item.fileExistsCached();
|
|
||||||
let icon = "";
|
let icon = "";
|
||||||
if (exists !== null) {
|
let ariaLabel;
|
||||||
if (item.isPDFAttachment()) {
|
// If the item has a child attachment
|
||||||
|
if (type !== null && type != 'none') {
|
||||||
|
if (type == 'pdf') {
|
||||||
icon = getDOMElement('IconTreeitemAttachmentPDF');
|
icon = getDOMElement('IconTreeitemAttachmentPDF');
|
||||||
|
ariaLabel = Zotero.getString('pane.item.attachments.hasPDF');
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
icon.classList.add('icon-missing-file');
|
icon.classList.add('icon-missing-file');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (item.isSnapshotAttachment()) {
|
else if (type == 'snapshot') {
|
||||||
//icon = getDOMElement('IconTreeitemAttachmentSnapshot');
|
//icon = getDOMElement('IconTreeitemAttachmentSnapshot');
|
||||||
icon = exists ? getDOMElement('IconBulletBlue') : getDOMElement('IconBulletBlueEmpty');
|
icon = exists ? getDOMElement('IconBulletBlue') : getDOMElement('IconBulletBlueEmpty');
|
||||||
|
ariaLabel = Zotero.getString('pane.item.attachments.hasSnapshot');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//icon = getDOMElement('IconTreeitem');
|
//icon = getDOMElement('IconTreeitem');
|
||||||
icon = exists ? getDOMElement('IconBulletBlue') : getDOMElement('IconBulletBlueEmpty');
|
icon = exists ? getDOMElement('IconBulletBlue') : getDOMElement('IconBulletBlueEmpty');
|
||||||
|
ariaLabel = Zotero.getString('pane.item.attachments.has');
|
||||||
}
|
}
|
||||||
icon.classList.add('cell-icon');
|
icon.classList.add('cell-icon');
|
||||||
//if (!exists) {
|
//if (!exists) {
|
||||||
// icon.classList.add('icon-missing-file');
|
// icon.classList.add('icon-missing-file');
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
//else if (type == 'none') {
|
||||||
|
// if (item.getField('url') || item.getField('DOI')) {
|
||||||
|
// icon = getDOMElement('IconLink');
|
||||||
|
// ariaLabel = Zotero.getString('pane.item.attachments.hasLink');
|
||||||
|
// icon.classList.add('cell-icon');
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
if (ariaLabel) {
|
||||||
|
icon.setAttribute('aria-label', ariaLabel + '.');
|
||||||
|
span.setAttribute('title', ariaLabel);
|
||||||
|
}
|
||||||
span.append(icon);
|
span.append(icon);
|
||||||
|
|
||||||
item.fileExists()
|
// Don't run this immediately since it might cause a db check and disk access
|
||||||
// TODO: With no cell refreshing this is possibly somewhat inefficient
|
// but delay for some time and see if the item is still visible in the tree
|
||||||
// Refresh cell when promise is fulfilled
|
// (i.e. if we haven't scrolled right past it)
|
||||||
.then(realExists => realExists != exists && this.tree.invalidateRow(index));
|
setTimeout(() => {
|
||||||
|
if (!this.tree.rowIsVisible(index)) return;
|
||||||
|
item.getBestAttachmentState()
|
||||||
|
// Refresh cell when promise is fulfilled
|
||||||
|
.then(({ type: newType, exists: newExists }) => {
|
||||||
|
if (newType !== type || newExists !== exists) {
|
||||||
|
this.tree.invalidateRow(index);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, ATTACHMENT_STATE_LOAD_DELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
return span;
|
return span;
|
||||||
|
|
@ -2911,7 +2903,7 @@ var ItemTree = class ItemTree extends LibraryTree {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accessibility
|
// Accessibility
|
||||||
div.setAttribute('role', 'row');
|
div.setAttribute('role', 'treeitem');
|
||||||
div.setAttribute('aria-level', this.getLevel(index) + 1);
|
div.setAttribute('aria-level', this.getLevel(index) + 1);
|
||||||
if (!this.isContainerEmpty(index)) {
|
if (!this.isContainerEmpty(index)) {
|
||||||
div.setAttribute('aria-expanded', this.isContainerOpen(index));
|
div.setAttribute('aria-expanded', this.isContainerOpen(index));
|
||||||
|
|
@ -3550,7 +3542,7 @@ var ItemTree = class ItemTree extends LibraryTree {
|
||||||
let t = new Date();
|
let t = new Date();
|
||||||
for (let i = 0; i < this._rows.length; i++) {
|
for (let i = 0; i < this._rows.length; i++) {
|
||||||
let item = this.getRow(i).ref;
|
let item = this.getRow(i).ref;
|
||||||
if (item.isRegularItem()) {
|
if (this._canGetBestAttachmentState(item)) {
|
||||||
await item.getBestAttachmentState();
|
await item.getBestAttachmentState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3825,9 +3817,9 @@ var ItemTree = class ItemTree extends LibraryTree {
|
||||||
return icon;
|
return icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
_isOnlyEmoji(str) {
|
_canGetBestAttachmentState(item) {
|
||||||
// Remove emoji and zero-width joiner and see if anything's left
|
return (item.isRegularItem() && item.numAttachments())
|
||||||
return !str.replace(EMOJI_RE, '').replace(/\u200D/g,'');
|
|| (item.isFileAttachment() && item.isTopLevelItem());
|
||||||
}
|
}
|
||||||
|
|
||||||
_getTagSwatch(tag, color) {
|
_getTagSwatch(tag, color) {
|
||||||
|
|
@ -3837,7 +3829,7 @@ var ItemTree = class ItemTree extends LibraryTree {
|
||||||
//
|
//
|
||||||
// TODO: Check for a maximum number of graphemes, which is hard to do
|
// TODO: Check for a maximum number of graphemes, which is hard to do
|
||||||
// https://stackoverflow.com/a/54369605
|
// https://stackoverflow.com/a/54369605
|
||||||
if (this._isOnlyEmoji(tag)) {
|
if (Zotero.Utilities.Internal.isOnlyEmoji(tag)) {
|
||||||
span.textContent = tag;
|
span.textContent = tag;
|
||||||
}
|
}
|
||||||
// Otherwise display color
|
// Otherwise display color
|
||||||
|
|
|
||||||
|
|
@ -207,6 +207,14 @@ const COLUMNS = [
|
||||||
flex: 1,
|
flex: 1,
|
||||||
zoteroPersist: new Set(["width", "hidden", "sortDirection"])
|
zoteroPersist: new Set(["width", "hidden", "sortDirection"])
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
dataKey: "number",
|
||||||
|
disabledIn: "feed",
|
||||||
|
submenu: true,
|
||||||
|
label: "itemFields.number",
|
||||||
|
flex: 1,
|
||||||
|
zoteroPersist: new Set(["width", "hidden", "sortDirection"])
|
||||||
|
},
|
||||||
{
|
{
|
||||||
dataKey: "pages",
|
dataKey: "pages",
|
||||||
disabledIn: "feed",
|
disabledIn: "feed",
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 4877f181b1a962ea3e26d23f12d1acba3ccce347
|
Subproject commit cb98d366912a0c0be361880e12fbc43cef6d383e
|
||||||
|
|
@ -520,7 +520,13 @@ var Zotero_LocateMenu = new function() {
|
||||||
if(attachment.attachmentLinkMode !== Zotero.Attachments.LINK_MODE_LINKED_URL) {
|
if(attachment.attachmentLinkMode !== Zotero.Attachments.LINK_MODE_LINKED_URL) {
|
||||||
var path = yield attachment.getFilePathAsync();
|
var path = yield attachment.getFilePathAsync();
|
||||||
if (path) {
|
if (path) {
|
||||||
var ext = Zotero.File.getExtension(Zotero.File.pathToFile(path));
|
try {
|
||||||
|
var ext = Zotero.File.getExtension(Zotero.File.pathToFile(path));
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
Zotero.logError(e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if(!attachment.attachmentContentType ||
|
if(!attachment.attachmentContentType ||
|
||||||
Zotero.MIME.hasNativeHandler(attachment.attachmentContentType, ext) ||
|
Zotero.MIME.hasNativeHandler(attachment.attachmentContentType, ext) ||
|
||||||
!Zotero.MIME.hasInternalHandler(attachment.attachmentContentType, ext)) {
|
!Zotero.MIME.hasInternalHandler(attachment.attachmentContentType, ext)) {
|
||||||
|
|
@ -589,9 +595,23 @@ var Zotero_LocateMenu = new function() {
|
||||||
this.icon = "chrome://zotero/skin/locate-library-lookup.png";
|
this.icon = "chrome://zotero/skin/locate-library-lookup.png";
|
||||||
this.canHandleItem = function (item) { return Zotero.Promise.resolve(item.isRegularItem()); };
|
this.canHandleItem = function (item) { return Zotero.Promise.resolve(item.isRegularItem()); };
|
||||||
this.handleItems = Zotero.Promise.method(function (items, event) {
|
this.handleItems = Zotero.Promise.method(function (items, event) {
|
||||||
// If no resolver configured, just switch to the default
|
// If no resolver configured, show error
|
||||||
if (!Zotero.Prefs.get('openURL.resolver')) {
|
if (!Zotero.Prefs.get('openURL.resolver')) {
|
||||||
Zotero.Prefs.clear('openURL.resolver')
|
let ps = Services.prompt;
|
||||||
|
let buttonFlags = (ps.BUTTON_POS_0) * (ps.BUTTON_TITLE_IS_STRING)
|
||||||
|
+ (ps.BUTTON_POS_1) * (ps.BUTTON_TITLE_CANCEL);
|
||||||
|
let index = ps.confirmEx(
|
||||||
|
null,
|
||||||
|
Zotero.getString('locate.libraryLookup.noResolver.title'),
|
||||||
|
Zotero.getString('locate.libraryLookup.noResolver.text', Zotero.appName),
|
||||||
|
buttonFlags,
|
||||||
|
Zotero.getString('general.openPreferences'),
|
||||||
|
null, null, null, {}
|
||||||
|
);
|
||||||
|
if (index == 0) {
|
||||||
|
Zotero.Utilities.Internal.openPreferences('zotero-prefpane-advanced');
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
var urls = [];
|
var urls = [];
|
||||||
for (let item of items) {
|
for (let item of items) {
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,6 @@ Components.utils.import("resource://gre/modules/Services.jsm");
|
||||||
import FilePicker from 'zotero/modules/filePicker';
|
import FilePicker from 'zotero/modules/filePicker';
|
||||||
|
|
||||||
Zotero_Preferences.Advanced = {
|
Zotero_Preferences.Advanced = {
|
||||||
DEFAULT_OPENURL_RESOLVER: 'https://www.worldcat.org/registry/gateway',
|
|
||||||
|
|
||||||
_openURLResolvers: null,
|
_openURLResolvers: null,
|
||||||
|
|
||||||
init: function () {
|
init: function () {
|
||||||
|
|
@ -462,12 +460,6 @@ Zotero_Preferences.Advanced = {
|
||||||
var menupopup = openURLMenu.firstChild;
|
var menupopup = openURLMenu.firstChild;
|
||||||
menupopup.innerHTML = '';
|
menupopup.innerHTML = '';
|
||||||
|
|
||||||
var defaultMenuItem = document.createElement('menuitem');
|
|
||||||
defaultMenuItem.setAttribute('label', Zotero.getString('general.default'));
|
|
||||||
defaultMenuItem.setAttribute('value', this.DEFAULT_OPENURL_RESOLVER);
|
|
||||||
defaultMenuItem.setAttribute('type', 'checkbox');
|
|
||||||
menupopup.appendChild(defaultMenuItem);
|
|
||||||
|
|
||||||
var customMenuItem = document.createElement('menuitem');
|
var customMenuItem = document.createElement('menuitem');
|
||||||
customMenuItem.setAttribute('label', Zotero.getString('general.custom'));
|
customMenuItem.setAttribute('label', Zotero.getString('general.custom'));
|
||||||
customMenuItem.setAttribute('value', 'custom');
|
customMenuItem.setAttribute('value', 'custom');
|
||||||
|
|
@ -521,13 +513,8 @@ Zotero_Preferences.Advanced = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default
|
// From directory
|
||||||
if (currentResolver == this.DEFAULT_OPENURL_RESOLVER) {
|
if (selectedName) {
|
||||||
openURLMenu.setAttribute('label', Zotero.getString('general.default'));
|
|
||||||
defaultMenuItem.setAttribute('checked', true);
|
|
||||||
Zotero.Prefs.clear('openURL.name');
|
|
||||||
}
|
|
||||||
else if (selectedName) {
|
|
||||||
openURLMenu.setAttribute('label', selectedName);
|
openURLMenu.setAttribute('label', selectedName);
|
||||||
// If we found a match, update stored name
|
// If we found a match, update stored name
|
||||||
Zotero.Prefs.set('openURL.name', selectedName);
|
Zotero.Prefs.set('openURL.name', selectedName);
|
||||||
|
|
@ -555,15 +542,8 @@ Zotero_Preferences.Advanced = {
|
||||||
var openURLServerField = document.getElementById('openURLServerField');
|
var openURLServerField = document.getElementById('openURLServerField');
|
||||||
var openURLVersionMenu = document.getElementById('openURLVersionMenu');
|
var openURLVersionMenu = document.getElementById('openURLVersionMenu');
|
||||||
|
|
||||||
// Default
|
|
||||||
if (event.target.value == this.DEFAULT_OPENURL_RESOLVER) {
|
|
||||||
Zotero.Prefs.clear('openURL.name');
|
|
||||||
Zotero.Prefs.clear('openURL.resolver');
|
|
||||||
Zotero.Prefs.clear('openURL.version');
|
|
||||||
openURLServerField.value = this.DEFAULT_OPENURL_RESOLVER;
|
|
||||||
}
|
|
||||||
// If "Custom" selected, clear URL field
|
// If "Custom" selected, clear URL field
|
||||||
else if (event.target.value == "custom") {
|
if (event.target.value == "custom") {
|
||||||
Zotero.Prefs.clear('openURL.name');
|
Zotero.Prefs.clear('openURL.name');
|
||||||
Zotero.Prefs.set('openURL.resolver', '');
|
Zotero.Prefs.set('openURL.resolver', '');
|
||||||
Zotero.Prefs.clear('openURL.version');
|
Zotero.Prefs.clear('openURL.version');
|
||||||
|
|
|
||||||
|
|
@ -89,11 +89,15 @@ Zotero_Preferences.Export = {
|
||||||
* Builds the note Quick Copy drop-down from the current global pref
|
* Builds the note Quick Copy drop-down from the current global pref
|
||||||
*/
|
*/
|
||||||
populateNoteQuickCopyList: async function () {
|
populateNoteQuickCopyList: async function () {
|
||||||
|
document.getElementById('noteQuickCopy-format-options').removeAttribute('hidden');
|
||||||
|
|
||||||
// Initialize default format drop-down
|
// Initialize default format drop-down
|
||||||
var format = Zotero.Prefs.get("export.noteQuickCopy.setting");
|
var format = Zotero.Prefs.get("export.noteQuickCopy.setting");
|
||||||
format = Zotero.QuickCopy.unserializeSetting(format);
|
format = Zotero.QuickCopy.unserializeSetting(format);
|
||||||
var menulist = document.getElementById("zotero-noteQuickCopy-menu");
|
var menulist = document.getElementById("zotero-noteQuickCopy-menu");
|
||||||
menulist.setAttribute('preference', "pref-noteQuickCopy-setting");
|
menulist.setAttribute('preference', "pref-noteQuickCopy-setting");
|
||||||
|
menulist.removeEventListener('command', this.updateNoteQuickCopyUI);
|
||||||
|
menulist.addEventListener('command', this.updateNoteQuickCopyUI);
|
||||||
|
|
||||||
if (!format) {
|
if (!format) {
|
||||||
format = menulist.value;
|
format = menulist.value;
|
||||||
|
|
@ -149,11 +153,42 @@ Zotero_Preferences.Export = {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var val = JSON.stringify({ mode: 'export', id: translator.translatorID });
|
var value = { mode: 'export', id: translator.translatorID };
|
||||||
|
if (translator.translatorID == format.id) {
|
||||||
|
value = format;
|
||||||
|
}
|
||||||
|
else if (translator.translatorID == Zotero.Translators.TRANSLATOR_ID_MARKDOWN_AND_RICH_TEXT) {
|
||||||
|
value = {
|
||||||
|
mode: 'export',
|
||||||
|
id: translator.translatorID,
|
||||||
|
markdownOptions: {
|
||||||
|
includeAppLinks: true
|
||||||
|
},
|
||||||
|
htmlOptions: {
|
||||||
|
includeAppLinks: false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (format.id == Zotero.Translators.TRANSLATOR_ID_NOTE_HTML && format.options) {
|
||||||
|
value.htmlOptions = format.options;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (translator.translatorID == Zotero.Translators.TRANSLATOR_ID_NOTE_HTML) {
|
||||||
|
value = {
|
||||||
|
mode: 'export',
|
||||||
|
id: translator.translatorID,
|
||||||
|
options: {
|
||||||
|
includeAppLinks: false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (format.id == Zotero.Translators.TRANSLATOR_ID_MARKDOWN_AND_RICH_TEXT && format.htmlOptions) {
|
||||||
|
value.options = format.htmlOptions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
value = JSON.stringify(value);
|
||||||
var itemNode = document.createElement('menuitem');
|
var itemNode = document.createElement('menuitem');
|
||||||
itemNode.setAttribute('value', val);
|
itemNode.setAttribute('value', value);
|
||||||
itemNode.setAttribute('label', translator.label);
|
itemNode.setAttribute('label', translator.label);
|
||||||
// itemNode.setAttribute('oncommand', 'Zotero_Preferences.Export.updateQuickCopyUI()');
|
|
||||||
popup.appendChild(itemNode);
|
popup.appendChild(itemNode);
|
||||||
|
|
||||||
if (format.mode == 'export' && format.id == translator.translatorID) {
|
if (format.mode == 'export' && format.id == translator.translatorID) {
|
||||||
|
|
@ -162,6 +197,76 @@ Zotero_Preferences.Export = {
|
||||||
});
|
});
|
||||||
|
|
||||||
menulist.click();
|
menulist.click();
|
||||||
|
this.updateNoteQuickCopyUI();
|
||||||
|
},
|
||||||
|
|
||||||
|
updateNoteQuickCopyUI: () => {
|
||||||
|
var format = document.getElementById('zotero-noteQuickCopy-menu').value;
|
||||||
|
format = JSON.parse(format);
|
||||||
|
|
||||||
|
var markdownOptions = document.getElementById('noteQuickCopy-markdown-options');
|
||||||
|
var htmlOptions = document.getElementById('noteQuickCopy-html-options');
|
||||||
|
var markdownOptionsLabel = document.querySelector('#noteQuickCopy-markdown-options label');
|
||||||
|
var htmlOptionsLabel = document.querySelector('#noteQuickCopy-html-options label');
|
||||||
|
var markdownIncludeAppLinks = document.getElementById("noteQuickCopy-markdown-includeAppLinks");
|
||||||
|
var htmlIncludeAppLinks = document.getElementById("noteQuickCopy-html-includeAppLinks");
|
||||||
|
|
||||||
|
markdownOptionsLabel.value = Zotero.Utilities.Internal.stringWithColon("Markdown");
|
||||||
|
htmlOptionsLabel.value = Zotero.Utilities.Internal.stringWithColon(
|
||||||
|
Zotero.getString('zotero.preferences.export.quickCopy.note.htmlOptions.label')
|
||||||
|
);
|
||||||
|
markdownIncludeAppLinks.label = Zotero.getString('exportOptions.includeAppLinks', Zotero.appName);
|
||||||
|
htmlIncludeAppLinks.label = Zotero.getString('exportOptions.includeAppLinks', Zotero.appName);
|
||||||
|
|
||||||
|
if (format.id == Zotero.Translators.TRANSLATOR_ID_MARKDOWN_AND_RICH_TEXT) {
|
||||||
|
markdownOptions.hidden = false;
|
||||||
|
htmlOptions.hidden = false;
|
||||||
|
markdownIncludeAppLinks.checked = format.markdownOptions && format.markdownOptions.includeAppLinks;
|
||||||
|
htmlIncludeAppLinks.checked = format.htmlOptions && format.htmlOptions.includeAppLinks;
|
||||||
|
}
|
||||||
|
else if (format.id == Zotero.Translators.TRANSLATOR_ID_NOTE_HTML) {
|
||||||
|
markdownOptions.hidden = true;
|
||||||
|
htmlOptions.hidden = false;
|
||||||
|
htmlIncludeAppLinks.checked = format.options && format.options.includeAppLinks;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
markdownOptions.hidden = true;
|
||||||
|
htmlOptions.hidden = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onUpdateNoteExportOptions() {
|
||||||
|
var menulist = document.getElementById("zotero-noteQuickCopy-menu");
|
||||||
|
var markdownIncludeAppLinks = document.getElementById("noteQuickCopy-markdown-includeAppLinks");
|
||||||
|
var htmlIncludeAppLinks = document.getElementById("noteQuickCopy-html-includeAppLinks");
|
||||||
|
|
||||||
|
for (let i = 0; i < menulist.itemCount; i++) {
|
||||||
|
let item = menulist.getItemAtIndex(i);
|
||||||
|
let format = JSON.parse(item.getAttribute('value'));
|
||||||
|
if (format.id == Zotero.Translators.TRANSLATOR_ID_MARKDOWN_AND_RICH_TEXT) {
|
||||||
|
if (!format.markdownOptions) {
|
||||||
|
format.markdownOptions = {};
|
||||||
|
}
|
||||||
|
if (!format.htmlOptions) {
|
||||||
|
format.htmlOptions = {};
|
||||||
|
}
|
||||||
|
format.markdownOptions.includeAppLinks = markdownIncludeAppLinks.checked;
|
||||||
|
format.htmlOptions.includeAppLinks = htmlIncludeAppLinks.checked;
|
||||||
|
}
|
||||||
|
else if (format.id == Zotero.Translators.TRANSLATOR_ID_NOTE_HTML) {
|
||||||
|
if (!format.options) {
|
||||||
|
format.options = {};
|
||||||
|
}
|
||||||
|
format.options.includeAppLinks = htmlIncludeAppLinks.checked;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
item.value = JSON.stringify(format);
|
||||||
|
}
|
||||||
|
// After updating menulist item value we have to wait a bit before doing click(), to avoid anomalies
|
||||||
|
// like an empty row in menulist. 0 in setTimeout is not enough
|
||||||
|
setTimeout(() => menulist.click(), 50);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,35 @@
|
||||||
<label value="&zotero.preferences.quickCopy.noteFormat;" control="zotero-noteQuickCopy-menu"/>
|
<label value="&zotero.preferences.quickCopy.noteFormat;" control="zotero-noteQuickCopy-menu"/>
|
||||||
<menulist id="zotero-noteQuickCopy-menu" label="&zotero.general.loading;"/>
|
<menulist id="zotero-noteQuickCopy-menu" label="&zotero.general.loading;"/>
|
||||||
|
|
||||||
|
<table id="noteQuickCopy-format-options"
|
||||||
|
xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||||
|
hidden="hidden">
|
||||||
|
<tbody id="noteQuickCopy-markdown-options">
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
<xul:label/>
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
<xul:checkbox id="noteQuickCopy-markdown-includeAppLinks"
|
||||||
|
oncommand="Zotero_Preferences.Export.onUpdateNoteExportOptions()"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
<tbody id="noteQuickCopy-html-options">
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
<xul:label/>
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
<xul:checkbox id="noteQuickCopy-html-includeAppLinks"
|
||||||
|
oncommand="Zotero_Preferences.Export.onUpdateNoteExportOptions()"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
<separator/>
|
<separator/>
|
||||||
|
|
||||||
<label value="&zotero.preferences.quickCopy.siteEditor.setings;" control="quickCopy-siteSettings"/>
|
<label value="&zotero.preferences.quickCopy.siteEditor.setings;" control="quickCopy-siteSettings"/>
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,25 @@
|
||||||
<menuitem id="menu_copy"/>
|
<menuitem id="menu_copy"/>
|
||||||
<menuitem id="menu_paste"/>
|
<menuitem id="menu_paste"/>
|
||||||
<menuitem id="menu_delete"/>
|
<menuitem id="menu_delete"/>
|
||||||
|
<menuseparator class="menu-type-reader"/>
|
||||||
|
<menuitem
|
||||||
|
id="edit-menuitem-rotate-left"
|
||||||
|
class="menu-type-reader"
|
||||||
|
label="&zotero.pdfReader.rotatePageLeft;"
|
||||||
|
oncommand="menuCmd('rotateLeft')"
|
||||||
|
/>
|
||||||
|
<menuitem
|
||||||
|
id="edit-menuitem-rotate-right"
|
||||||
|
class="menu-type-reader"
|
||||||
|
label="&zotero.pdfReader.rotatePageRight;"
|
||||||
|
oncommand="menuCmd('rotateRight')"
|
||||||
|
/>
|
||||||
|
<!--<menuitem
|
||||||
|
id="edit-menuitem-rotate-180"
|
||||||
|
class="menu-type-reader"
|
||||||
|
label="&zotero.pdfReader.rotatePage180;"
|
||||||
|
oncommand="menuCmd('rotate180')"
|
||||||
|
/>-->
|
||||||
</menupopup>
|
</menupopup>
|
||||||
</menu>
|
</menu>
|
||||||
<menu label="View" onpopupshowing="onViewMenuOpen()">
|
<menu label="View" onpopupshowing="onViewMenuOpen()">
|
||||||
|
|
@ -81,15 +100,6 @@
|
||||||
-->
|
-->
|
||||||
<!-- <menuitem label="Switch to Presentation Mode" oncommand="menuCmd('presentationmode')"/>-->
|
<!-- <menuitem label="Switch to Presentation Mode" oncommand="menuCmd('presentationmode')"/>-->
|
||||||
<!-- <menuseparator/>-->
|
<!-- <menuseparator/>-->
|
||||||
<menuitem
|
|
||||||
label="&zotero.pdfReader.rotateClockwise;"
|
|
||||||
oncommand="menuCmd('rotatecw')"
|
|
||||||
/>
|
|
||||||
<menuitem
|
|
||||||
label="&zotero.pdfReader.rotateCounterclockwise;"
|
|
||||||
oncommand="menuCmd('rotateccw')"
|
|
||||||
/>
|
|
||||||
<menuseparator/>
|
|
||||||
<menuitem
|
<menuitem
|
||||||
id="view-menuitem-hand-tool"
|
id="view-menuitem-hand-tool"
|
||||||
label="&zotero.pdfReader.handTool;"
|
label="&zotero.pdfReader.handTool;"
|
||||||
|
|
@ -163,6 +173,19 @@
|
||||||
label="&zotero.pdfReader.zoomPageHeight;"
|
label="&zotero.pdfReader.zoomPageHeight;"
|
||||||
oncommand="menuCmd('zoomPageHeight')"
|
oncommand="menuCmd('zoomPageHeight')"
|
||||||
/>
|
/>
|
||||||
|
<menuseparator class="menu-type-reader"/>
|
||||||
|
<menuitem
|
||||||
|
id="view-menuitem-split-horizontally"
|
||||||
|
type="checkbox"
|
||||||
|
label="&zotero.pdfReader.splitHorizontally;"
|
||||||
|
oncommand="menuCmd('splitHorizontally')"
|
||||||
|
/>
|
||||||
|
<menuitem
|
||||||
|
id="view-menuitem-split-vertically"
|
||||||
|
type="checkbox"
|
||||||
|
label="&zotero.pdfReader.splitVertically;"
|
||||||
|
oncommand="menuCmd('splitVertically')"
|
||||||
|
/>
|
||||||
</menupopup>
|
</menupopup>
|
||||||
</menu>
|
</menu>
|
||||||
<menu
|
<menu
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,8 @@ var Zotero_Report_Interface = new function() {
|
||||||
*/
|
*/
|
||||||
this.loadCollectionReport = function () {
|
this.loadCollectionReport = function () {
|
||||||
var sortColumn = ZoteroPane_Local.getSortField();
|
var sortColumn = ZoteroPane_Local.getSortField();
|
||||||
var sortDirection = ZoteroPane_Local.getSortDirection();
|
|
||||||
var queryString = '?sort=' + sortColumn
|
var queryString = '?sort=' + sortColumn
|
||||||
+ '&direction=' + (sortDirection == 'ascending' ? 'asc' : 'desc');
|
+ '&direction=' + (ZoteroPane.getSortDirection() == 1 ? 'asc' : 'desc');
|
||||||
|
|
||||||
var url = 'zotero://report/';
|
var url = 'zotero://report/';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -160,8 +160,7 @@ const ZoteroStandalone = new function() {
|
||||||
let item = Zotero.Items.get(reader.itemID);
|
let item = Zotero.Items.get(reader.itemID);
|
||||||
let library = Zotero.Libraries.get(item.libraryID);
|
let library = Zotero.Libraries.get(item.libraryID);
|
||||||
if (item
|
if (item
|
||||||
// Don't allow annotation transfer in group libraries
|
&& library.filesEditable
|
||||||
&& library.libraryType == 'user'
|
|
||||||
&& library.editable
|
&& library.editable
|
||||||
&& !(item.deleted || item.parentItem && item.parentItem.deleted)) {
|
&& !(item.deleted || item.parentItem && item.parentItem.deleted)) {
|
||||||
let annotations = item.getAnnotations();
|
let annotations = item.getAnnotations();
|
||||||
|
|
@ -192,12 +191,9 @@ const ZoteroStandalone = new function() {
|
||||||
if (numFiles) {
|
if (numFiles) {
|
||||||
menuitem.hidden = false;
|
menuitem.hidden = false;
|
||||||
sep.hidden = false;
|
sep.hidden = false;
|
||||||
if (numFiles == 1) {
|
menuitem.label = Zotero.getString(
|
||||||
menuitem.label = 'Export PDF…';
|
'pane.items.menu.exportPDF' + (numFiles == 1 ? '' : '.multiple')
|
||||||
}
|
);
|
||||||
else {
|
|
||||||
menuitem.label = 'Export PDFs…';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
menuitem.hidden = true;
|
menuitem.hidden = true;
|
||||||
|
|
@ -408,6 +404,8 @@ const ZoteroStandalone = new function() {
|
||||||
this.updateMenuItemCheckmark('view-menuitem-zoom-auto', reader.isZoomAutoActive());
|
this.updateMenuItemCheckmark('view-menuitem-zoom-auto', reader.isZoomAutoActive());
|
||||||
this.updateMenuItemCheckmark('view-menuitem-zoom-page-width', reader.isZoomPageWidthActive());
|
this.updateMenuItemCheckmark('view-menuitem-zoom-page-width', reader.isZoomPageWidthActive());
|
||||||
this.updateMenuItemCheckmark('view-menuitem-zoom-page-height', reader.isZoomPageHeightActive());
|
this.updateMenuItemCheckmark('view-menuitem-zoom-page-height', reader.isZoomPageHeightActive());
|
||||||
|
this.updateMenuItemCheckmark('view-menuitem-split-vertically', reader.isSplitVerticallyActive());
|
||||||
|
this.updateMenuItemCheckmark('view-menuitem-split-horizontally', reader.isSplitHorizontallyActive());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Layout mode
|
// Layout mode
|
||||||
|
|
|
||||||
|
|
@ -232,6 +232,25 @@
|
||||||
label="&bidiSwitchTextDirectionItem.label;"
|
label="&bidiSwitchTextDirectionItem.label;"
|
||||||
accesskey="&bidiSwitchTextDirectionItem.accesskey;"
|
accesskey="&bidiSwitchTextDirectionItem.accesskey;"
|
||||||
hidden="true"/>
|
hidden="true"/>
|
||||||
|
<menuseparator class="menu-type-reader"/>
|
||||||
|
<menuitem
|
||||||
|
id="edit-menuitem-rotate-left"
|
||||||
|
class="menu-type-reader"
|
||||||
|
label="&zotero.pdfReader.rotatePageLeft;"
|
||||||
|
oncommand="ZoteroStandalone.onReaderCmd('rotateLeft')"
|
||||||
|
/>
|
||||||
|
<menuitem
|
||||||
|
id="edit-menuitem-rotate-right"
|
||||||
|
class="menu-type-reader"
|
||||||
|
label="&zotero.pdfReader.rotatePageRight;"
|
||||||
|
oncommand="ZoteroStandalone.onReaderCmd('rotateRight')"
|
||||||
|
/>
|
||||||
|
<!--<menuitem
|
||||||
|
id="edit-menuitem-rotate-180"
|
||||||
|
class="menu-type-reader"
|
||||||
|
label="&zotero.pdfReader.rotatePage180;"
|
||||||
|
oncommand="ZoteroStandalone.onReaderCmd('rotate180')"
|
||||||
|
/>-->
|
||||||
</menupopup>
|
</menupopup>
|
||||||
</menu>
|
</menu>
|
||||||
|
|
||||||
|
|
@ -240,17 +259,6 @@
|
||||||
accesskey="&viewMenu.accesskey;"
|
accesskey="&viewMenu.accesskey;"
|
||||||
onpopupshowing="ZoteroStandalone.onViewMenuOpen()">
|
onpopupshowing="ZoteroStandalone.onViewMenuOpen()">
|
||||||
<menupopup id="menu_viewPopup">
|
<menupopup id="menu_viewPopup">
|
||||||
<menuitem
|
|
||||||
class="menu-type-reader"
|
|
||||||
label="&zotero.pdfReader.rotateClockwise;"
|
|
||||||
oncommand="ZoteroStandalone.onReaderCmd('rotatecw')"
|
|
||||||
/>
|
|
||||||
<menuitem
|
|
||||||
class="menu-type-reader"
|
|
||||||
label="&zotero.pdfReader.rotateCounterclockwise;"
|
|
||||||
oncommand="ZoteroStandalone.onReaderCmd('rotateccw')"
|
|
||||||
/>
|
|
||||||
<menuseparator class="menu-type-reader"/>
|
|
||||||
<menuitem
|
<menuitem
|
||||||
id="view-menuitem-hand-tool"
|
id="view-menuitem-hand-tool"
|
||||||
class="menu-type-reader"
|
class="menu-type-reader"
|
||||||
|
|
@ -337,6 +345,21 @@
|
||||||
oncommand="ZoteroStandalone.onReaderCmd('zoomPageHeight')"
|
oncommand="ZoteroStandalone.onReaderCmd('zoomPageHeight')"
|
||||||
/>
|
/>
|
||||||
<menuseparator class="menu-type-reader"/>
|
<menuseparator class="menu-type-reader"/>
|
||||||
|
<menuitem
|
||||||
|
id="view-menuitem-split-horizontally"
|
||||||
|
class="menu-type-reader"
|
||||||
|
type="checkbox"
|
||||||
|
label="&zotero.pdfReader.splitHorizontally;"
|
||||||
|
oncommand="ZoteroStandalone.onReaderCmd('splitHorizontally')"
|
||||||
|
/>
|
||||||
|
<menuitem
|
||||||
|
id="view-menuitem-split-vertically"
|
||||||
|
class="menu-type-reader"
|
||||||
|
type="checkbox"
|
||||||
|
label="&zotero.pdfReader.splitVertically;"
|
||||||
|
oncommand="ZoteroStandalone.onReaderCmd('splitVertically')"
|
||||||
|
/>
|
||||||
|
<menuseparator class="menu-type-reader"/>
|
||||||
|
|
||||||
<menu id="layout-menu" label="&layout.label;">
|
<menu id="layout-menu" label="&layout.label;">
|
||||||
<menupopup oncommand="ZoteroStandalone.onViewMenuItemClick(event)">
|
<menupopup oncommand="ZoteroStandalone.onViewMenuItemClick(event)">
|
||||||
|
|
@ -390,6 +413,8 @@
|
||||||
<menuitem label="12" type="checkbox"/>
|
<menuitem label="12" type="checkbox"/>
|
||||||
<menuitem label="13" type="checkbox"/>
|
<menuitem label="13" type="checkbox"/>
|
||||||
<menuitem label="14" type="checkbox"/>
|
<menuitem label="14" type="checkbox"/>
|
||||||
|
<menuitem label="15" type="checkbox"/>
|
||||||
|
<menuitem label="16" type="checkbox"/>
|
||||||
<menuitem label="18" type="checkbox"/>
|
<menuitem label="18" type="checkbox"/>
|
||||||
<menuitem label="24" type="checkbox"/>
|
<menuitem label="24" type="checkbox"/>
|
||||||
<menuitem label="36" type="checkbox"/>
|
<menuitem label="36" type="checkbox"/>
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,9 @@ var React = require('react');
|
||||||
var ReactDOM = require('react-dom');
|
var ReactDOM = require('react-dom');
|
||||||
import TabBar from 'components/tabBar';
|
import TabBar from 'components/tabBar';
|
||||||
|
|
||||||
const MAX_LOADED_TABS = 5;
|
// Reduce loaded tabs limit if the system has 8 GB or less memory.
|
||||||
|
// TODO: Revise this after upgrading to Zotero 7
|
||||||
|
const MAX_LOADED_TABS = Services.sysinfo.getProperty("memsize") / 1024 / 1024 / 1024 <= 8 ? 2 : 5;
|
||||||
const UNLOAD_UNUSED_AFTER = 86400; // 24h
|
const UNLOAD_UNUSED_AFTER = 86400; // 24h
|
||||||
|
|
||||||
var Zotero_Tabs = new function () {
|
var Zotero_Tabs = new function () {
|
||||||
|
|
@ -84,6 +86,17 @@ var Zotero_Tabs = new function () {
|
||||||
window.Zotero_Tooltip.stop();
|
window.Zotero_Tooltip.stop();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.getTabIDByItemID = function (itemID) {
|
||||||
|
let tab = this._tabs.find(tab => tab.data && tab.data.itemID === itemID);
|
||||||
|
return tab && tab.id;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.setSecondViewState = function (tabID, state) {
|
||||||
|
let { tab } = this._getTab(tabID);
|
||||||
|
tab.data.secondViewState = state;
|
||||||
|
Zotero.Session.debounceSave();
|
||||||
|
};
|
||||||
|
|
||||||
this.init = function () {
|
this.init = function () {
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<TabBar
|
<TabBar
|
||||||
|
|
@ -128,12 +141,24 @@ var Zotero_Tabs = new function () {
|
||||||
}
|
}
|
||||||
else if (tab.type === 'reader') {
|
else if (tab.type === 'reader') {
|
||||||
if (Zotero.Items.exists(tab.data.itemID)) {
|
if (Zotero.Items.exists(tab.data.itemID)) {
|
||||||
this.add({
|
if (tab.selected) {
|
||||||
type: 'reader-unloaded',
|
Zotero.Reader.open(tab.data.itemID,
|
||||||
title: tab.title,
|
null,
|
||||||
index: i,
|
{
|
||||||
data: tab.data
|
title: tab.title,
|
||||||
});
|
openInBackground: !tab.selected,
|
||||||
|
secondViewState: tab.data.secondViewState
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.add({
|
||||||
|
type: 'reader-unloaded',
|
||||||
|
title: tab.title,
|
||||||
|
index: i,
|
||||||
|
data: tab.data
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -152,7 +177,7 @@ var Zotero_Tabs = new function () {
|
||||||
* @param {Function} onClose
|
* @param {Function} onClose
|
||||||
* @return {{ id: string, container: XULElement}} id - tab id, container - a new tab container created in the deck
|
* @return {{ id: string, container: XULElement}} id - tab id, container - a new tab container created in the deck
|
||||||
*/
|
*/
|
||||||
this.add = function ({ type, data, title, index, select, onClose }) {
|
this.add = function ({ id, type, data, title, index, select, onClose }) {
|
||||||
if (typeof type != 'string') {
|
if (typeof type != 'string') {
|
||||||
}
|
}
|
||||||
if (typeof title != 'string') {
|
if (typeof title != 'string') {
|
||||||
|
|
@ -164,7 +189,7 @@ var Zotero_Tabs = new function () {
|
||||||
if (onClose !== undefined && typeof onClose != 'function') {
|
if (onClose !== undefined && typeof onClose != 'function') {
|
||||||
throw new Error(`'onClose' should be a function (was ${typeof onClose})`);
|
throw new Error(`'onClose' should be a function (was ${typeof onClose})`);
|
||||||
}
|
}
|
||||||
var id = 'tab-' + Zotero.Utilities.randomString();
|
id = id || 'tab-' + Zotero.Utilities.randomString();
|
||||||
var container = document.createElement('vbox');
|
var container = document.createElement('vbox');
|
||||||
container.id = id;
|
container.id = id;
|
||||||
this.deck.appendChild(container);
|
this.deck.appendChild(container);
|
||||||
|
|
@ -251,7 +276,7 @@ var Zotero_Tabs = new function () {
|
||||||
closedIDs.push(id);
|
closedIDs.push(id);
|
||||||
}
|
}
|
||||||
this._history.push(historyEntry);
|
this._history.push(historyEntry);
|
||||||
Zotero.Notifier.trigger('close', 'tab', [closedIDs]);
|
Zotero.Notifier.trigger('close', 'tab', [closedIDs], true);
|
||||||
this._update();
|
this._update();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -321,7 +346,7 @@ var Zotero_Tabs = new function () {
|
||||||
* @param {String} id
|
* @param {String} id
|
||||||
* @param {Boolean} reopening
|
* @param {Boolean} reopening
|
||||||
*/
|
*/
|
||||||
this.select = function (id, reopening) {
|
this.select = function (id, reopening, options) {
|
||||||
var { tab, tabIndex } = this._getTab(id);
|
var { tab, tabIndex } = this._getTab(id);
|
||||||
if (!tab || tab.id === this._selectedID) {
|
if (!tab || tab.id === this._selectedID) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -332,10 +357,12 @@ var Zotero_Tabs = new function () {
|
||||||
}
|
}
|
||||||
if (tab.type === 'reader-unloaded') {
|
if (tab.type === 'reader-unloaded') {
|
||||||
this.close(tab.id);
|
this.close(tab.id);
|
||||||
Zotero.Reader.open(tab.data.itemID, null, {
|
Zotero.Reader.open(tab.data.itemID, options && options.location, {
|
||||||
|
tabID: tab.id,
|
||||||
title: tab.title,
|
title: tab.title,
|
||||||
tabIndex,
|
tabIndex,
|
||||||
allowDuplicate: true
|
allowDuplicate: true,
|
||||||
|
secondViewState: tab.data.secondViewState
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -385,6 +412,7 @@ var Zotero_Tabs = new function () {
|
||||||
}
|
}
|
||||||
this.close(tab.id);
|
this.close(tab.id);
|
||||||
this.add({
|
this.add({
|
||||||
|
id: tab.id,
|
||||||
type: 'reader-unloaded',
|
type: 'reader-unloaded',
|
||||||
title: tab.title,
|
title: tab.title,
|
||||||
index: tabIndex,
|
index: tabIndex,
|
||||||
|
|
@ -440,7 +468,7 @@ var Zotero_Tabs = new function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
this._openMenu = function (x, y, id) {
|
this._openMenu = function (x, y, id) {
|
||||||
var { tabIndex } = this._getTab(id);
|
var { tab, tabIndex } = this._getTab(id);
|
||||||
window.Zotero_Tooltip.stop();
|
window.Zotero_Tooltip.stop();
|
||||||
let menuitem;
|
let menuitem;
|
||||||
let popup = document.createElement('menupopup');
|
let popup = document.createElement('menupopup');
|
||||||
|
|
@ -497,7 +525,8 @@ var Zotero_Tabs = new function () {
|
||||||
var reader = Zotero.Reader.getByTabID(id);
|
var reader = Zotero.Reader.getByTabID(id);
|
||||||
if (reader) {
|
if (reader) {
|
||||||
this.close(id);
|
this.close(id);
|
||||||
Zotero.Reader.open(reader.itemID, null, { openInWindow: true });
|
let { secondViewState } = tab.data;
|
||||||
|
Zotero.Reader.open(reader.itemID, null, { openInWindow: true, secondViewState });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
menupopup.appendChild(menuitem);
|
menupopup.appendChild(menuitem);
|
||||||
|
|
@ -505,11 +534,10 @@ var Zotero_Tabs = new function () {
|
||||||
menuitem = document.createElement('menuitem');
|
menuitem = document.createElement('menuitem');
|
||||||
menuitem.setAttribute('label', Zotero.getString('tabs.duplicate'));
|
menuitem.setAttribute('label', Zotero.getString('tabs.duplicate'));
|
||||||
menuitem.addEventListener('command', () => {
|
menuitem.addEventListener('command', () => {
|
||||||
var { tab, tabIndex } = this._getTab(id);
|
|
||||||
if (tab.data.itemID) {
|
if (tab.data.itemID) {
|
||||||
tabIndex++;
|
tabIndex++;
|
||||||
Zotero.Reader.open(tab.data.itemID, null, { tabIndex, allowDuplicate: true });
|
let { secondViewState } = tab.data;
|
||||||
|
Zotero.Reader.open(tab.data.itemID, null, { tabIndex, allowDuplicate: true, secondViewState });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
popup.appendChild(menuitem);
|
popup.appendChild(menuitem);
|
||||||
|
|
|
||||||
|
|
@ -59,10 +59,8 @@ var Zotero_CSL_Editor = new function() {
|
||||||
|
|
||||||
var pageList = document.getElementById('zotero-csl-page-type');
|
var pageList = document.getElementById('zotero-csl-page-type');
|
||||||
var locators = Zotero.Cite.labels;
|
var locators = Zotero.Cite.labels;
|
||||||
for (let type of locators) {
|
for (let locator of locators) {
|
||||||
var locator = type;
|
pageList.appendItem(Zotero.Cite.getLocatorString(locator), locator);
|
||||||
locator = Zotero.getString('citation.locator.'+locator.replace(/\s/g,''));
|
|
||||||
pageList.appendItem(locator, type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pageList.selectedIndex = 0;
|
pageList.selectedIndex = 0;
|
||||||
|
|
|
||||||
|
|
@ -177,7 +177,7 @@ Zotero.Annotations = new function () {
|
||||||
o.tags = tags;
|
o.tags = tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
o.dateModified = item.dateModified;
|
o.dateModified = Zotero.Date.sqlToISO8601(item.dateModified);
|
||||||
return o;
|
return o;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -270,7 +270,7 @@ Zotero.Attachments = new function(){
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Object} options - 'file', 'url', 'title', 'contentType', 'charset', 'parentItemID', 'singleFile'
|
* @param {Object} options - 'file', 'url', 'title', 'contentType', 'charset', 'libraryID', 'parentItemID', 'singleFile'
|
||||||
* @param {Object} [options.saveOptions] - Options to pass to Zotero.Item::save()
|
* @param {Object} [options.saveOptions] - Options to pass to Zotero.Item::save()
|
||||||
* @return {Promise<Zotero.Item>}
|
* @return {Promise<Zotero.Item>}
|
||||||
*/
|
*/
|
||||||
|
|
@ -287,10 +287,19 @@ Zotero.Attachments = new function(){
|
||||||
var title = options.title;
|
var title = options.title;
|
||||||
var contentType = options.contentType;
|
var contentType = options.contentType;
|
||||||
var charset = options.charset;
|
var charset = options.charset;
|
||||||
|
var libraryID = options.libraryID;
|
||||||
var parentItemID = options.parentItemID;
|
var parentItemID = options.parentItemID;
|
||||||
var saveOptions = options.saveOptions;
|
var saveOptions = options.saveOptions;
|
||||||
|
|
||||||
if (!parentItemID) {
|
if (parentItemID) {
|
||||||
|
libraryID = Zotero.Items.getLibraryAndKeyFromID(parentItemID).libraryID;
|
||||||
|
}
|
||||||
|
else if (contentType == 'text/html') {
|
||||||
|
throw new Error("parentItemID not provided");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Webpage snapshots must have parent items
|
||||||
|
if (!parentItemID && contentType == 'text/html') {
|
||||||
throw new Error("parentItemID not provided");
|
throw new Error("parentItemID not provided");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -299,8 +308,9 @@ Zotero.Attachments = new function(){
|
||||||
yield Zotero.DB.executeTransaction(function* () {
|
yield Zotero.DB.executeTransaction(function* () {
|
||||||
// Create a new attachment
|
// Create a new attachment
|
||||||
attachmentItem = new Zotero.Item('attachment');
|
attachmentItem = new Zotero.Item('attachment');
|
||||||
let {libraryID, key: parentKey} = Zotero.Items.getLibraryAndKeyFromID(parentItemID);
|
if (libraryID) {
|
||||||
attachmentItem.libraryID = libraryID;
|
attachmentItem.libraryID = libraryID;
|
||||||
|
}
|
||||||
attachmentItem.setField('title', title);
|
attachmentItem.setField('title', title);
|
||||||
attachmentItem.setField('url', url);
|
attachmentItem.setField('url', url);
|
||||||
attachmentItem.parentID = parentItemID;
|
attachmentItem.parentID = parentItemID;
|
||||||
|
|
@ -563,7 +573,8 @@ Zotero.Attachments = new function(){
|
||||||
reject(e);
|
reject(e);
|
||||||
},
|
},
|
||||||
true,
|
true,
|
||||||
cookieSandbox
|
cookieSandbox,
|
||||||
|
{ allowImages: true }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
@ -1143,67 +1154,82 @@ Zotero.Attachments = new function(){
|
||||||
*/
|
*/
|
||||||
this.downloadPDFViaBrowser = async function (url, path, options = {}) {
|
this.downloadPDFViaBrowser = async function (url, path, options = {}) {
|
||||||
Zotero.debug(`downloadPDFViaBrowser: Downloading file via browser from ${url}`);
|
Zotero.debug(`downloadPDFViaBrowser: Downloading file via browser from ${url}`);
|
||||||
const onLoadTimeout = 1e3;
|
const onLoadTimeout = Zotero.Prefs.get('downloadPDFViaBrowser.onLoadTimeout');
|
||||||
// Technically this is not a download, but the full operation timeout
|
// Technically this is not a download, but the full operation timeout
|
||||||
const downloadTimeout = 60e3;
|
const downloadTimeout = Zotero.Prefs.get('downloadPDFViaBrowser.downloadTimeout');
|
||||||
let channelBrowser, hiddenBrowser;
|
let channelBrowser, hiddenBrowser;
|
||||||
let hiddenBrowserPDFFoundDeferred = Zotero.Promise.defer();
|
let hiddenBrowserPDFFoundDeferred = Zotero.Promise.defer();
|
||||||
|
|
||||||
var pdfMIMETypeHandler = async (blob, name, _, channel) => {
|
let isOurPDF = false;
|
||||||
Zotero.debug(`downloadPDFViaBrowser: Sniffing a PDF loaded at ${name}`);
|
var pdfMIMETypeHandler = {
|
||||||
|
onStartRequest: function (name, _, channel) {
|
||||||
let isOurPDF = false;
|
Zotero.debug(`downloadPDFViaBrowser: Sniffing a PDF loaded at ${name}`);
|
||||||
// try the browser
|
// try the browser
|
||||||
try {
|
|
||||||
channelBrowser = channel.notificationCallbacks.getInterface(Ci.nsIWebNavigation)
|
|
||||||
.QueryInterface(Ci.nsIDocShell).chromeEventHandler;
|
|
||||||
}
|
|
||||||
catch (e) {}
|
|
||||||
if (channelBrowser) {
|
|
||||||
isOurPDF = hiddenBrowser === channelBrowser;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// try the document for the load group
|
|
||||||
try {
|
try {
|
||||||
channelBrowser = channel.loadGroup.notificationCallbacks.getInterface(Ci.nsIWebNavigation)
|
channelBrowser = channel.notificationCallbacks.getInterface(Ci.nsIWebNavigation)
|
||||||
.QueryInterface(Ci.nsIDocShell).chromeEventHandler;
|
.QueryInterface(Ci.nsIDocShell).chromeEventHandler;
|
||||||
}
|
}
|
||||||
catch(e) {}
|
catch (e) {}
|
||||||
if (channelBrowser) {
|
if (channelBrowser) {
|
||||||
isOurPDF = hiddenBrowser === channelBrowser;
|
isOurPDF = hiddenBrowser === channelBrowser;
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
|
// try the document for the load group
|
||||||
if (isOurPDF) {
|
try {
|
||||||
Zotero.debug(`downloadPDFViaBrowser: Found our PDF at ${name}`);
|
channelBrowser = channel.loadGroup.notificationCallbacks.getInterface(Ci.nsIWebNavigation)
|
||||||
await Zotero.File.putContentsAsync(path, blob);
|
.QueryInterface(Ci.nsIDocShell).chromeEventHandler;
|
||||||
hiddenBrowserPDFFoundDeferred.resolve();
|
}
|
||||||
return true;
|
catch(e) {}
|
||||||
}
|
if (channelBrowser) {
|
||||||
else {
|
isOurPDF = hiddenBrowser === channelBrowser;
|
||||||
Zotero.debug(`downloadPDFViaBrowser: Not our PDF at ${name}`);
|
}
|
||||||
return false;
|
}
|
||||||
|
},
|
||||||
|
onContent: async (blob, name, _, channel) => {
|
||||||
|
if (isOurPDF) {
|
||||||
|
Zotero.debug(`downloadPDFViaBrowser: Found our PDF at ${name}`);
|
||||||
|
await Zotero.File.putContentsAsync(path, blob);
|
||||||
|
hiddenBrowserPDFFoundDeferred.resolve();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Zotero.debug(`downloadPDFViaBrowser: Not our PDF at ${name}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
Zotero.MIMETypeHandler.addHandler("application/pdf", pdfMIMETypeHandler, true);
|
Zotero.MIMETypeHandler.addHandlers("application/pdf", pdfMIMETypeHandler, true);
|
||||||
let noop = () => 0;
|
function noop() {};
|
||||||
hiddenBrowser = Zotero.HTTP.loadDocuments([url], noop, noop, noop, true, options.cookieSandbox);
|
hiddenBrowser = Zotero.HTTP.loadDocuments([url], noop, noop, noop, true, options.cookieSandbox);
|
||||||
let onLoadTimeoutDeferred = Zotero.Promise.defer();
|
let onLoadTimeoutDeferred = Zotero.Promise.defer();
|
||||||
hiddenBrowser.addEventListener("load", async function onLoad() {
|
let currentUrl = "";
|
||||||
Zotero.debug(`downloadPDFViaBrowser: Page with potential JS redirect loaded, giving it ${onLoadTimeout}ms to process`);
|
hiddenBrowser.addProgressListener({
|
||||||
hiddenBrowser.addEventListener("unload", () => {
|
QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsIWebProgressListener,
|
||||||
Zotero.debug(`downloadPDFViaBrowser: A JS redirect occurred, short timeout cancelled`);
|
Components.interfaces.nsISupportsWeakReference]),
|
||||||
hiddenBrowser.removeEventListener('load', onLoad);
|
onProgressChange: noop,
|
||||||
});
|
onStateChange: noop,
|
||||||
await Zotero.Promise.delay(onLoadTimeout);
|
onStatusChange: noop,
|
||||||
onLoadTimeoutDeferred.reject(`Loading PDF via browser timed out on the JS challenge page after ${onLoadTimeout}ms`);
|
onSecurityChange: noop,
|
||||||
}, true);
|
async onLocationChange() {
|
||||||
|
let url = hiddenBrowser.contentDocument.location.href;
|
||||||
|
if (currentUrl) {
|
||||||
|
Zotero.debug(`downloadPDFViaBrowser: A JS redirect occurred to ${hiddenBrowser.contentDocument.location.href}`);
|
||||||
|
}
|
||||||
|
currentUrl = url;
|
||||||
|
Zotero.debug(`downloadPDFViaBrowser: Page with potential JS redirect loaded, giving it ${onLoadTimeout}ms to process`);
|
||||||
|
await Zotero.Promise.delay(onLoadTimeout);
|
||||||
|
// If URL changed that means we got redirected and the onLoadTimeout needs to restart
|
||||||
|
if (currentUrl === url && !isOurPDF) {
|
||||||
|
onLoadTimeoutDeferred.reject(new Error(`downloadPDFViaBrowser: Loading PDF via browser timed out on the JS challenge page after ${onLoadTimeout}ms`));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
await Zotero.Promise.race([
|
await Zotero.Promise.race([
|
||||||
onLoadTimeoutDeferred.promise,
|
onLoadTimeoutDeferred.promise,
|
||||||
Zotero.Promise.delay(downloadTimeout).then(() => {
|
Zotero.Promise.delay(downloadTimeout).then(() => {
|
||||||
if (!hiddenBrowserPDFFoundDeferred.promise.isResolved()) {
|
if (!isOurPDF) {
|
||||||
throw new Error(`Loading PDF via browser timed out after ${downloadTimeout}ms`);
|
throw new Error(`downloadPDFViaBrowser: Loading PDF via browser timed out after ${downloadTimeout}ms`);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
hiddenBrowserPDFFoundDeferred.promise
|
hiddenBrowserPDFFoundDeferred.promise
|
||||||
|
|
@ -1213,13 +1239,13 @@ Zotero.Attachments = new function(){
|
||||||
try {
|
try {
|
||||||
await OS.File.remove(path, { ignoreAbsent: true });
|
await OS.File.remove(path, { ignoreAbsent: true });
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (err) {
|
||||||
Zotero.logError(e, 1);
|
Zotero.logError(err);
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
Zotero.MIMETypeHandler.removeHandler('application/pdf', pdfMIMETypeHandler);
|
Zotero.MIMETypeHandler.removeHandlers('application/pdf', pdfMIMETypeHandler);
|
||||||
if (hiddenBrowser) {
|
if (hiddenBrowser) {
|
||||||
Zotero.Browser.deleteHiddenBrowser(hiddenBrowser);
|
Zotero.Browser.deleteHiddenBrowser(hiddenBrowser);
|
||||||
}
|
}
|
||||||
|
|
@ -1259,13 +1285,14 @@ Zotero.Attachments = new function(){
|
||||||
|
|
||||||
this.canFindPDFForItem = function (item) {
|
this.canFindPDFForItem = function (item) {
|
||||||
return item.isRegularItem()
|
return item.isRegularItem()
|
||||||
|
&& !item.isFeedItem
|
||||||
&& (!!item.getField('DOI') || !!item.getField('url') || !!item.getExtraField('DOI'))
|
&& (!!item.getField('DOI') || !!item.getField('url') || !!item.getExtraField('DOI'))
|
||||||
&& item.numPDFAttachments() == 0;
|
&& item.numPDFAttachments() == 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Look for an available PDF for an item and add it as an attachment
|
* Get the PDF resolvers that can be used for a given item based on the available fields
|
||||||
*
|
*
|
||||||
* @param {Zotero.Item} item
|
* @param {Zotero.Item} item
|
||||||
* @param {String[]} [methods=['doi', 'url', 'oa', 'custom']]
|
* @param {String[]} [methods=['doi', 'url', 'oa', 'custom']]
|
||||||
|
|
@ -2011,7 +2038,7 @@ Zotero.Attachments = new function(){
|
||||||
addTriedURL(url);
|
addTriedURL(url);
|
||||||
// Backoff loop
|
// Backoff loop
|
||||||
let tries = 3;
|
let tries = 3;
|
||||||
while (tries-- >= 0) {
|
while (tries-- > 0) {
|
||||||
try {
|
try {
|
||||||
await beforeRequest(url);
|
await beforeRequest(url);
|
||||||
await this.downloadFile(url, path, options);
|
await this.downloadFile(url, path, options);
|
||||||
|
|
@ -2043,14 +2070,22 @@ Zotero.Attachments = new function(){
|
||||||
let contentType;
|
let contentType;
|
||||||
let skip = false;
|
let skip = false;
|
||||||
let domains = new Set();
|
let domains = new Set();
|
||||||
|
let redirectLimit = 10;
|
||||||
|
let redirectURLTries = new Map();
|
||||||
while (true) {
|
while (true) {
|
||||||
|
if (redirectLimit == 0) {
|
||||||
|
Zotero.debug("Too many redirects -- stopping");
|
||||||
|
skip = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
let domain = urlToDomain(nextURL);
|
let domain = urlToDomain(nextURL);
|
||||||
let noDelay = domains.has(domain);
|
let noDelay = domains.has(domain);
|
||||||
domains.add(domain);
|
domains.add(domain);
|
||||||
|
|
||||||
// Backoff loop
|
// Backoff loop
|
||||||
let tries = 3;
|
let tries = 3;
|
||||||
while (tries-- >= 0) {
|
while (tries-- > 0) {
|
||||||
try {
|
try {
|
||||||
await beforeRequest(nextURL, noDelay);
|
await beforeRequest(nextURL, noDelay);
|
||||||
req = await Zotero.HTTP.request(
|
req = await Zotero.HTTP.request(
|
||||||
|
|
@ -2058,7 +2093,9 @@ Zotero.Attachments = new function(){
|
||||||
nextURL,
|
nextURL,
|
||||||
{
|
{
|
||||||
responseType: 'blob',
|
responseType: 'blob',
|
||||||
followRedirects: false
|
followRedirects: false,
|
||||||
|
// Use our own error handling
|
||||||
|
errorDelayMax: 0
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -2069,22 +2106,39 @@ Zotero.Attachments = new function(){
|
||||||
noDelay = false;
|
noDelay = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
throw e;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
afterRequest(nextURL);
|
afterRequest(nextURL);
|
||||||
|
if (!req) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
if ([301, 302, 303, 307].includes(req.status)) {
|
if ([301, 302, 303, 307].includes(req.status)) {
|
||||||
let location = req.getResponseHeader('Location');
|
let location = req.getResponseHeader('Location');
|
||||||
if (!location) {
|
if (!location) {
|
||||||
throw new Error("Location header not provided");
|
throw new Error("Location header not provided");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let currentURL = nextURL;
|
||||||
|
|
||||||
nextURL = Services.io.newURI(nextURL, null, null).resolve(location);
|
nextURL = Services.io.newURI(nextURL, null, null).resolve(location);
|
||||||
if (isTriedURL(nextURL)) {
|
if (isTriedURL(nextURL)) {
|
||||||
Zotero.debug("Redirect URL has already been tried -- skipping");
|
Zotero.debug("Redirect URL has already been tried -- skipping");
|
||||||
skip = true;
|
skip = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Keep track of tries for each redirect URL, and stop if too many
|
||||||
|
let maxTriesPerRedirectURL = 2;
|
||||||
|
let tries = (redirectURLTries.get(currentURL) || 0) + 1;
|
||||||
|
if (tries > maxTriesPerRedirectURL) {
|
||||||
|
Zotero.debug(`Too many redirects to ${currentURL} -- stopping`);
|
||||||
|
skip = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
redirectURLTries.set(currentURL, tries);
|
||||||
|
// And keep track of total redirects for this chain
|
||||||
|
redirectLimit--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2131,7 +2185,7 @@ Zotero.Attachments = new function(){
|
||||||
}
|
}
|
||||||
|
|
||||||
// If DOI resolves directly to a PDF, save it to disk
|
// If DOI resolves directly to a PDF, save it to disk
|
||||||
if (contentType.startsWith('application/pdf')) {
|
if (contentType && contentType.startsWith('application/pdf')) {
|
||||||
Zotero.debug("URL resolves directly to PDF");
|
Zotero.debug("URL resolves directly to PDF");
|
||||||
await Zotero.File.putContentsAsync(path, blob);
|
await Zotero.File.putContentsAsync(path, blob);
|
||||||
await _enforcePDF(path);
|
await _enforcePDF(path);
|
||||||
|
|
@ -2147,7 +2201,7 @@ Zotero.Attachments = new function(){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!url) {
|
if (!url) {
|
||||||
Zotero.debug(`No PDF found on ${responseURL}`);
|
Zotero.debug(`No PDF found on ${responseURL || pageURL}`);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (isTriedURL(url)) {
|
if (isTriedURL(url)) {
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,110 @@ Zotero.Cite = {
|
||||||
/**
|
/**
|
||||||
* Locator labels
|
* Locator labels
|
||||||
*/
|
*/
|
||||||
"labels":["page", "book", "chapter", "column", "figure", "folio",
|
"labels": [
|
||||||
"issue", "line", "note", "opus", "paragraph", "part", "section", "sub verbo",
|
"act",
|
||||||
"volume", "verse"],
|
"appendix",
|
||||||
|
"article-locator",
|
||||||
|
"book",
|
||||||
|
"canon",
|
||||||
|
"chapter",
|
||||||
|
"column",
|
||||||
|
"elocation",
|
||||||
|
"equation",
|
||||||
|
"figure",
|
||||||
|
"folio",
|
||||||
|
"issue",
|
||||||
|
"line",
|
||||||
|
"note",
|
||||||
|
"opus",
|
||||||
|
"page",
|
||||||
|
"paragraph",
|
||||||
|
"part",
|
||||||
|
"rule",
|
||||||
|
"scene",
|
||||||
|
"section",
|
||||||
|
"sub-verbo",
|
||||||
|
"table",
|
||||||
|
//"timestamp",
|
||||||
|
"title-locator",
|
||||||
|
"verse",
|
||||||
|
"volume"
|
||||||
|
],
|
||||||
|
|
||||||
|
_locatorStrings: new Map(),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get localized string for locator
|
||||||
|
*
|
||||||
|
* @param {String} locator - Locator name (e.g., 'book')
|
||||||
|
* @return {String} - Localized string (e.g., 'Livre')
|
||||||
|
*/
|
||||||
|
getLocatorString: function (locator) {
|
||||||
|
// 'timestamp' not included in CSL locales
|
||||||
|
if (locator == 'timestamp') {
|
||||||
|
return Zotero.getString('citation.locator.timestamp');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the best CSL locale for the current Zotero locale
|
||||||
|
var cslLocale = Zotero.Utilities.Internal.resolveLocale(
|
||||||
|
Zotero.locale,
|
||||||
|
Object.keys(Zotero.Styles.locales)
|
||||||
|
);
|
||||||
|
|
||||||
|
// If locator strings are already cached for the current locale, use that
|
||||||
|
if (this._locatorStrings.has(cslLocale)) {
|
||||||
|
return this._locatorStrings.get(cslLocale).get(locator);
|
||||||
|
}
|
||||||
|
var map = new Map();
|
||||||
|
this._locatorStrings.set(cslLocale, map);
|
||||||
|
|
||||||
|
var localeXML = Zotero.Cite.Locale.get(cslLocale);
|
||||||
|
var parser;
|
||||||
|
if (Zotero.platformMajorVersion > 60) {
|
||||||
|
parser = new DOMParser();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
parser = Components.classes["@mozilla.org/xmlextras/domparser;1"]
|
||||||
|
.createInstance(Components.interfaces.nsIDOMParser);
|
||||||
|
}
|
||||||
|
var doc = parser.parseFromString(localeXML, 'text/xml');
|
||||||
|
var englishDoc;
|
||||||
|
// Cache all locators for the current locale
|
||||||
|
for (let locator of this.labels) {
|
||||||
|
let elem = doc.querySelector(`term[name="${locator}"]:not([form="short"]) > single`);
|
||||||
|
if (!elem) {
|
||||||
|
// If locator not found, get from the U.S. English locale
|
||||||
|
if (cslLocale != 'en-US') {
|
||||||
|
Zotero.logError(`Locator '${locator}' not found in ${cslLocale} locale -- trying en-US`);
|
||||||
|
if (!englishDoc) {
|
||||||
|
englishDoc = parser.parseFromString(Zotero.Cite.Locale.get('en-US'), 'text/xml');
|
||||||
|
}
|
||||||
|
elem = englishDoc.querySelector(`term[name="${locator}"]:not([form="short"]) > single`);
|
||||||
|
if (!elem) {
|
||||||
|
Zotero.logError(`Locator '${locator}' not found in en-US locale -- using name`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Zotero.logError(`Locator '${locator}' not found in en-US locale -- using name`);
|
||||||
|
}
|
||||||
|
// If still not found, use the locator name directly
|
||||||
|
if (!elem) {
|
||||||
|
map.set(locator, Zotero.Utilities.capitalize(locator));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If <single> is empty, use the locator name directly
|
||||||
|
let str = elem.textContent;
|
||||||
|
if (!str) {
|
||||||
|
Zotero.logError(`Locator '${locator}' is empty in ${cslLocale} locale -- using name`);
|
||||||
|
map.set(locator, Zotero.Utilities.capitalize(locator));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
map.set(locator, Zotero.Utilities.capitalize(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
return map.get(locator);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove specified item IDs in-place from a citeproc-js bibliography object returned
|
* Remove specified item IDs in-place from a citeproc-js bibliography object returned
|
||||||
|
|
|
||||||
|
|
@ -22261,7 +22261,7 @@ CSL.Output.Formats.prototype.text = {
|
||||||
return "\n"+str;
|
return "\n"+str;
|
||||||
},
|
},
|
||||||
"@display/left-margin": function (state, str) {
|
"@display/left-margin": function (state, str) {
|
||||||
return str;
|
return str + " ";
|
||||||
},
|
},
|
||||||
"@display/right-inline": function (state, str) {
|
"@display/right-inline": function (state, str) {
|
||||||
return str;
|
return str;
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ Zotero.HTTPIntegrationClient.Application = function() {
|
||||||
this.supportedNotes = ['footnotes'];
|
this.supportedNotes = ['footnotes'];
|
||||||
this.supportsImportExport = false;
|
this.supportsImportExport = false;
|
||||||
this.supportsTextInsertion = false;
|
this.supportsTextInsertion = false;
|
||||||
|
this.supportsCitationMerging = false;
|
||||||
this.processorName = "HTTP Integration";
|
this.processorName = "HTTP Integration";
|
||||||
};
|
};
|
||||||
Zotero.HTTPIntegrationClient.Application.prototype = {
|
Zotero.HTTPIntegrationClient.Application.prototype = {
|
||||||
|
|
@ -70,6 +71,7 @@ Zotero.HTTPIntegrationClient.Application.prototype = {
|
||||||
this.supportedNotes = result.supportedNotes || this.supportedNotes;
|
this.supportedNotes = result.supportedNotes || this.supportedNotes;
|
||||||
this.supportsImportExport = result.supportsImportExport || this.supportsImportExport;
|
this.supportsImportExport = result.supportsImportExport || this.supportsImportExport;
|
||||||
this.supportsTextInsertion = result.supportsTextInsertion || this.supportsTextInsertion;
|
this.supportsTextInsertion = result.supportsTextInsertion || this.supportsTextInsertion;
|
||||||
|
this.supportsCitationMerging = result.supportsCitationMerging || this.supportsCitationMerging;
|
||||||
this.processorName = result.processorName || this.processorName;
|
this.processorName = result.processorName || this.processorName;
|
||||||
return new Zotero.HTTPIntegrationClient.Document(result.documentID, this.processorName);
|
return new Zotero.HTTPIntegrationClient.Document(result.documentID, this.processorName);
|
||||||
}
|
}
|
||||||
|
|
@ -168,6 +170,10 @@ Zotero.HTTPIntegrationClient.Field = function(documentID, json) {
|
||||||
this._code = json.code;
|
this._code = json.code;
|
||||||
this._text = json.text;
|
this._text = json.text;
|
||||||
this._noteIndex = json.noteIndex;
|
this._noteIndex = json.noteIndex;
|
||||||
|
this._adjacent = json.adjacent;
|
||||||
|
if (this._adjacent !== 'undefined') {
|
||||||
|
this.isAdjacentToNextField = this._isAdjacentToNextField;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
Zotero.HTTPIntegrationClient.Field.prototype = {};
|
Zotero.HTTPIntegrationClient.Field.prototype = {};
|
||||||
|
|
||||||
|
|
@ -202,3 +208,6 @@ Zotero.HTTPIntegrationClient.Field.prototype.getNoteIndex = async function() {
|
||||||
Zotero.HTTPIntegrationClient.Field.prototype.equals = async function(arg) {
|
Zotero.HTTPIntegrationClient.Field.prototype.equals = async function(arg) {
|
||||||
return this._id === arg._id;
|
return this._id === arg._id;
|
||||||
};
|
};
|
||||||
|
Zotero.HTTPIntegrationClient.Field.prototype._isAdjacentToNextField = async function() {
|
||||||
|
return this._adjacent;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1689,9 +1689,8 @@ Zotero.Server.Connector.Ping.prototype = {
|
||||||
*/
|
*/
|
||||||
init: function (req) {
|
init: function (req) {
|
||||||
if (req.method == 'GET') {
|
if (req.method == 'GET') {
|
||||||
return [200, "text/html", '<!DOCTYPE html><html><head>' +
|
return [200, "text/html", '<!DOCTYPE html><html>'
|
||||||
'<title>Zotero Connector Server is Available</title></head>' +
|
+ '<body>Zotero is running</body></html>'];
|
||||||
'<body>Zotero Connector Server is Available</body></html>'];
|
|
||||||
} else {
|
} else {
|
||||||
// Store the active URL so it can be used for site-specific Quick Copy
|
// Store the active URL so it can be used for site-specific Quick Copy
|
||||||
if (req.data.activeURL) {
|
if (req.data.activeURL) {
|
||||||
|
|
|
||||||
|
|
@ -384,6 +384,10 @@ Zotero.CookieSandbox.Observer = new function() {
|
||||||
var cookiesForURI = trackedBy.getCookiesForURI(channel.URI);
|
var cookiesForURI = trackedBy.getCookiesForURI(channel.URI);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (trackedBy && trackedBy.userAgent) {
|
||||||
|
channel.setRequestHeader("User-Agent", trackedBy.userAgent, false);
|
||||||
|
}
|
||||||
|
|
||||||
if(!trackedBy || !cookiesForURI) {
|
if(!trackedBy || !cookiesForURI) {
|
||||||
channel.setRequestHeader("Cookie", "", false);
|
channel.setRequestHeader("Cookie", "", false);
|
||||||
channel.setRequestHeader("Cookie2", "", false);
|
channel.setRequestHeader("Cookie2", "", false);
|
||||||
|
|
@ -391,10 +395,6 @@ Zotero.CookieSandbox.Observer = new function() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(trackedBy.userAgent) {
|
|
||||||
channel.setRequestHeader("User-Agent", trackedBy.userAgent, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// add cookies to be sent to this domain
|
// add cookies to be sent to this domain
|
||||||
channel.setRequestHeader("Cookie", Zotero.CookieSandbox.generateCookieString(cookiesForURI), false);
|
channel.setRequestHeader("Cookie", Zotero.CookieSandbox.generateCookieString(cookiesForURI), false);
|
||||||
Zotero.debug("CookieSandbox: Added cookies for request to "+channelURI, 5);
|
Zotero.debug("CookieSandbox: Added cookies for request to "+channelURI, 5);
|
||||||
|
|
|
||||||
|
|
@ -275,7 +275,7 @@ Zotero.DataObjectUtilities = {
|
||||||
var pred2 = Object.keys(data2);
|
var pred2 = Object.keys(data2);
|
||||||
pred2.sort();
|
pred2.sort();
|
||||||
if (!Zotero.Utilities.arrayEquals(pred1, pred2)) return true;
|
if (!Zotero.Utilities.arrayEquals(pred1, pred2)) return true;
|
||||||
for (let pred in pred1) {
|
for (let pred of pred1) {
|
||||||
let vals1 = typeof data1[pred] == 'string' ? [data1[pred]] : data1[pred];
|
let vals1 = typeof data1[pred] == 'string' ? [data1[pred]] : data1[pred];
|
||||||
let vals2 = (!data2[pred] || data2[pred] === '')
|
let vals2 = (!data2[pred] || data2[pred] === '')
|
||||||
? []
|
? []
|
||||||
|
|
|
||||||
|
|
@ -133,8 +133,9 @@ Zotero.Feeds = new function() {
|
||||||
for (let feedElem of feedElems) {
|
for (let feedElem of feedElems) {
|
||||||
let url = feedElem.getAttribute('xmlUrl');
|
let url = feedElem.getAttribute('xmlUrl');
|
||||||
if (!url) url = feedElem.getAttribute('url');
|
if (!url) url = feedElem.getAttribute('url');
|
||||||
let name = feedElem.getAttribute('title');
|
let name = feedElem.getAttribute('title')
|
||||||
if (!name) name = feedElem.getAttribute('text');
|
|| feedElem.getAttribute('text')
|
||||||
|
|| Zotero.getString('pane.collections.untitled');
|
||||||
if (Zotero.Feeds.existsByURL(url) || registeredUrls.has(url)) {
|
if (Zotero.Feeds.existsByURL(url) || registeredUrls.has(url)) {
|
||||||
Zotero.debug("Feed Import from OPML: Feed " + name + " : " + url + " already exists. Skipping");
|
Zotero.debug("Feed Import from OPML: Feed " + name + " : " + url + " already exists. Skipping");
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,16 @@ Zotero.defineProperty(Zotero.Item.prototype, 'parentItemKey', {
|
||||||
Zotero.defineProperty(Zotero.Item.prototype, 'parentItem', {
|
Zotero.defineProperty(Zotero.Item.prototype, 'parentItem', {
|
||||||
get: function() { return Zotero.Items.get(this.parentID) || undefined; },
|
get: function() { return Zotero.Items.get(this.parentID) || undefined; },
|
||||||
});
|
});
|
||||||
|
Zotero.defineProperty(Zotero.Item.prototype, 'topLevelItem', {
|
||||||
|
get: function () {
|
||||||
|
var item = this; // eslint-disable-line consistent-this
|
||||||
|
var parentItem;
|
||||||
|
while ((parentItem = item.parentItem)) {
|
||||||
|
item = parentItem;
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Zotero.defineProperty(Zotero.Item.prototype, 'firstCreator', {
|
Zotero.defineProperty(Zotero.Item.prototype, 'firstCreator', {
|
||||||
get: function() { return this._firstCreator; }
|
get: function() { return this._firstCreator; }
|
||||||
|
|
@ -768,7 +777,7 @@ Zotero.Item.prototype.setField = function(field, value, loadIn) {
|
||||||
|
|
||||||
if (value !== false && !Zotero.ItemFields.isValidForType(fieldID, itemTypeID)) {
|
if (value !== false && !Zotero.ItemFields.isValidForType(fieldID, itemTypeID)) {
|
||||||
let msg = "'" + field + "' is not a valid field for type '"
|
let msg = "'" + field + "' is not a valid field for type '"
|
||||||
+ Zotero.ItemFields.getName(itemTypeID) + "'";
|
+ Zotero.ItemTypes.getName(itemTypeID) + "'";
|
||||||
|
|
||||||
if (loadIn) {
|
if (loadIn) {
|
||||||
Zotero.debug(msg + " -- ignoring value '" + value + "'", 2);
|
Zotero.debug(msg + " -- ignoring value '" + value + "'", 2);
|
||||||
|
|
@ -3713,7 +3722,7 @@ Zotero.Item.prototype.getBestAttachments = Zotero.Promise.coroutine(function* ()
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return state of best attachment
|
* Return state of best attachment (or this item if it's a standalone attachment)
|
||||||
*
|
*
|
||||||
* @return {Promise<Object>} - Promise for object with string 'type' ('none'|'pdf'|'snapshot'|'other')
|
* @return {Promise<Object>} - Promise for object with string 'type' ('none'|'pdf'|'snapshot'|'other')
|
||||||
* and boolean 'exists'
|
* and boolean 'exists'
|
||||||
|
|
@ -3722,7 +3731,9 @@ Zotero.Item.prototype.getBestAttachmentState = async function () {
|
||||||
if (this._bestAttachmentState !== null) {
|
if (this._bestAttachmentState !== null) {
|
||||||
return this._bestAttachmentState;
|
return this._bestAttachmentState;
|
||||||
}
|
}
|
||||||
var item = await this.getBestAttachment();
|
var item = this.isAttachment() && this.isTopLevelItem()
|
||||||
|
? this
|
||||||
|
: await this.getBestAttachment();
|
||||||
if (!item) {
|
if (!item) {
|
||||||
return this._bestAttachmentState = {
|
return this._bestAttachmentState = {
|
||||||
type: 'none'
|
type: 'none'
|
||||||
|
|
@ -3953,6 +3964,29 @@ Zotero.Item.prototype.getAnnotations = function (includeTrashed) {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the item is a PDF attachment that exists on disk and contains
|
||||||
|
* embedded markup annotations.
|
||||||
|
*
|
||||||
|
* @return {Promise<Boolean>}
|
||||||
|
*/
|
||||||
|
Zotero.Item.prototype.hasEmbeddedAnnotations = async function () {
|
||||||
|
if (!this.isPDFAttachment()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let path = await this.getFilePathAsync();
|
||||||
|
if (!path) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let contents = await Zotero.File.getContentsAsync(path);
|
||||||
|
// Check for "markup" annotations per the PDF spec
|
||||||
|
// https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandards/PDF32000_2008.pdf, p. 390
|
||||||
|
let re = /\s\/Subtype\s+\/(Text|FreeText|Line|Square|Circle|Polygon|PolyLine|Highlight|Underline|Squiggly|StrikeOut|Stamp|Caret|Ink|FileAttachment|Sound|Redact)\s/;
|
||||||
|
return re.test(contents);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Methods dealing with item tags
|
// Methods dealing with item tags
|
||||||
|
|
|
||||||
|
|
@ -1035,6 +1035,29 @@ Zotero.Items = function() {
|
||||||
for (let otherItem of otherItems) {
|
for (let otherItem of otherItems) {
|
||||||
let mergedMasterAttachments = new Set();
|
let mergedMasterAttachments = new Set();
|
||||||
|
|
||||||
|
let doMerge = async (fromAttachment, toAttachment) => {
|
||||||
|
mergedMasterAttachments.add(toAttachment.id);
|
||||||
|
|
||||||
|
await this.moveChildItems(fromAttachment, toAttachment, true);
|
||||||
|
await this._moveEmbeddedNote(fromAttachment, toAttachment);
|
||||||
|
await this._moveRelations(fromAttachment, toAttachment);
|
||||||
|
|
||||||
|
fromAttachment.deleted = true;
|
||||||
|
await fromAttachment.save();
|
||||||
|
|
||||||
|
// Later on, when processing notes, we'll use this to remap
|
||||||
|
// URLs pointing to the old attachment.
|
||||||
|
remapAttachmentKeys.set(fromAttachment.key, toAttachment.key);
|
||||||
|
|
||||||
|
// Items can only have one replaced item predicate
|
||||||
|
if (!toAttachment.getRelationsByPredicate(Zotero.Relations.replacedItemPredicate)) {
|
||||||
|
toAttachment.addRelation(Zotero.Relations.replacedItemPredicate,
|
||||||
|
Zotero.URI.getItemURI(fromAttachment));
|
||||||
|
}
|
||||||
|
|
||||||
|
await toAttachment.save();
|
||||||
|
};
|
||||||
|
|
||||||
for (let otherAttachment of await this.getAsync(otherItem.getAttachments(true))) {
|
for (let otherAttachment of await this.getAsync(otherItem.getAttachments(true))) {
|
||||||
if (!otherAttachment.isPDFAttachment()) {
|
if (!otherAttachment.isPDFAttachment()) {
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -1065,13 +1088,12 @@ Zotero.Items = function() {
|
||||||
await otherAttachment.save();
|
await otherAttachment.save();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
mergedMasterAttachments.add(masterAttachmentID);
|
|
||||||
|
|
||||||
let masterAttachment = await this.getAsync(masterAttachmentID);
|
let masterAttachment = await this.getAsync(masterAttachmentID);
|
||||||
|
|
||||||
if (masterAttachment.attachmentContentType !== otherAttachment.attachmentContentType) {
|
if (masterAttachment.attachmentContentType !== otherAttachment.attachmentContentType) {
|
||||||
Zotero.debug(`Master attachment ${masterAttachment.key} matches ${otherAttachment.key}, `
|
Zotero.debug(`Master attachment ${masterAttachment.key} matches ${otherAttachment.key}, `
|
||||||
+ 'but content types differ - moving');
|
+ 'but content types differ - keeping both');
|
||||||
otherAttachment.parentItemID = item.id;
|
otherAttachment.parentItemID = item.id;
|
||||||
await otherAttachment.save();
|
await otherAttachment.save();
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -1080,31 +1102,35 @@ Zotero.Items = function() {
|
||||||
if (!((masterAttachment.isImportedAttachment() && otherAttachment.isImportedAttachment())
|
if (!((masterAttachment.isImportedAttachment() && otherAttachment.isImportedAttachment())
|
||||||
|| (masterAttachment.isLinkedFileAttachment() && otherAttachment.isLinkedFileAttachment()))) {
|
|| (masterAttachment.isLinkedFileAttachment() && otherAttachment.isLinkedFileAttachment()))) {
|
||||||
Zotero.debug(`Master attachment ${masterAttachment.key} matches ${otherAttachment.key}, `
|
Zotero.debug(`Master attachment ${masterAttachment.key} matches ${otherAttachment.key}, `
|
||||||
+ 'but link modes differ - moving');
|
+ 'but link modes differ - keeping both');
|
||||||
otherAttachment.parentItemID = item.id;
|
otherAttachment.parentItemID = item.id;
|
||||||
await otherAttachment.save();
|
await otherAttachment.save();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Zotero.debug(`Master attachment ${masterAttachment.key} matches ${otherAttachment.key} - merging`);
|
// Check whether master and other have embedded annotations
|
||||||
await this.moveChildItems(otherAttachment, masterAttachment, true);
|
// Master yes, other yes -> keep both
|
||||||
await this._moveEmbeddedNote(otherAttachment, masterAttachment);
|
// Master yes, other no -> keep master
|
||||||
await this._moveRelations(otherAttachment, masterAttachment);
|
// Master no, other yes -> keep other
|
||||||
|
if (await otherAttachment.hasEmbeddedAnnotations()) {
|
||||||
otherAttachment.deleted = true;
|
if (await masterAttachment.hasEmbeddedAnnotations()) {
|
||||||
await otherAttachment.save();
|
Zotero.debug(`Master attachment ${masterAttachment.key} matches ${otherAttachment.key}, `
|
||||||
|
+ 'but both have embedded annotations - keeping both');
|
||||||
// Later on, when processing notes, we'll use this to remap
|
otherAttachment.parentItemID = item.id;
|
||||||
// URLs pointing to the old attachment.
|
await otherAttachment.save();
|
||||||
remapAttachmentKeys.set(otherAttachment.key, masterAttachment.key);
|
}
|
||||||
|
else {
|
||||||
// Items can only have one replaced item predicate
|
Zotero.debug(`Master attachment ${masterAttachment.key} matches ${otherAttachment.key}, `
|
||||||
if (!masterAttachment.getRelationsByPredicate(Zotero.Relations.replacedItemPredicate)) {
|
+ 'but other has embedded annotations - merging into other');
|
||||||
masterAttachment.addRelation(Zotero.Relations.replacedItemPredicate,
|
await doMerge(masterAttachment, otherAttachment);
|
||||||
Zotero.URI.getItemURI(otherAttachment));
|
otherAttachment.parentItemID = item.id;
|
||||||
|
await otherAttachment.save();
|
||||||
|
}
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
await masterAttachment.save();
|
Zotero.debug(`Master attachment ${masterAttachment.key} matches ${otherAttachment.key} - merging into master`);
|
||||||
|
await doMerge(otherAttachment, masterAttachment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1477,6 +1503,7 @@ Zotero.Items = function() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Zotero.debug("Emptied " + deleted.length + " item(s) from trash in " + (new Date() - t) + " ms");
|
Zotero.debug("Emptied " + deleted.length + " item(s) from trash in " + (new Date() - t) + " ms");
|
||||||
|
Zotero.Notifier.trigger('refresh', 'trash', libraryID);
|
||||||
}
|
}
|
||||||
|
|
||||||
return deleted.length;
|
return deleted.length;
|
||||||
|
|
@ -1709,22 +1736,40 @@ Zotero.Items = function() {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of items with children of selected parents removed
|
* Get the top-level items of all passed items
|
||||||
*
|
*
|
||||||
|
* @param {Zotero.Item[]} items
|
||||||
* @return {Zotero.Item[]}
|
* @return {Zotero.Item[]}
|
||||||
*/
|
*/
|
||||||
this.keepParents = function (items) {
|
this.getTopLevel = function (items) {
|
||||||
var parentItems = new Set(
|
return [...new Set(items.map(item => item.topLevelItem))];
|
||||||
items
|
};
|
||||||
.filter(item => item.isTopLevelItem())
|
|
||||||
.map(item => item.id)
|
|
||||||
|
/**
|
||||||
|
* Return an array of items with descendants of selected top-level items removed
|
||||||
|
*
|
||||||
|
* Non-top-level items that aren't descendents of selected items are kept.
|
||||||
|
*
|
||||||
|
* @param {Zotero.Item[]}
|
||||||
|
* @return {Zotero.Item[]}
|
||||||
|
*/
|
||||||
|
this.keepTopLevel = function (items) {
|
||||||
|
var topLevelItems = new Set(
|
||||||
|
items.filter(item => item.isTopLevelItem())
|
||||||
);
|
);
|
||||||
return items.filter(item => {
|
return items.filter((item) => {
|
||||||
var parentItemID = item.parentItemID;
|
var topLevelItem = !item.isTopLevelItem() && item.topLevelItem;
|
||||||
// Not a child item or not a child of one of the passed items
|
// Not a child item or not a child of one of the passed items
|
||||||
return !parentItemID || !parentItems.has(parentItemID);
|
return !topLevelItem || !topLevelItems.has(topLevelItem);
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
|
this.keepParents = function (items) {
|
||||||
|
Zotero.debug("Zotero.Items.keepParents() is deprecated -- use Zotero.Items.keepTopLevel() instead");
|
||||||
|
return this.keepTopLevel(items);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -2013,6 +2058,28 @@ Zotero.Items = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find attachment items whose paths begin with the passed `pathPrefix` and don't exist on disk
|
||||||
|
*
|
||||||
|
* @param {Number} libraryID
|
||||||
|
* @param {String} pathPrefix
|
||||||
|
* @return {Zotero.Item[]}
|
||||||
|
*/
|
||||||
|
this.findMissingLinkedFiles = async function (libraryID, pathPrefix) {
|
||||||
|
let sql = "SELECT itemID FROM items JOIN itemAttachments USING (itemID) "
|
||||||
|
+ "WHERE itemID NOT IN (SELECT itemID FROM deletedItems) "
|
||||||
|
+ `AND linkMode=${Zotero.Attachments.LINK_MODE_LINKED_FILE} `
|
||||||
|
+ "AND path LIKE ? ESCAPE '\\' "
|
||||||
|
+ "AND libraryID=?";
|
||||||
|
let ids = await Zotero.DB.columnQueryAsync(sql, [Zotero.DB.escapeSQLExpression(pathPrefix) + '%', libraryID]);
|
||||||
|
let items = await this.getAsync(ids);
|
||||||
|
let missingItems = await Promise.all(
|
||||||
|
items.map(async item => (await item.fileExists() ? false : item))
|
||||||
|
);
|
||||||
|
return missingItems.filter(Boolean);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
Zotero.DataObjects.call(this);
|
Zotero.DataObjects.call(this);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
|
|
|
||||||
|
|
@ -948,7 +948,11 @@ Zotero.Search.idsToTempTable = Zotero.Promise.coroutine(function* (ids) {
|
||||||
Zotero.Search.prototype._buildQuery = Zotero.Promise.coroutine(function* () {
|
Zotero.Search.prototype._buildQuery = Zotero.Promise.coroutine(function* () {
|
||||||
this._requireData('conditions');
|
this._requireData('conditions');
|
||||||
|
|
||||||
var sql = 'SELECT itemID FROM items';
|
// TEMP: Match parent attachment for annotation matches
|
||||||
|
// var sql = 'SELECT itemID FROM items';
|
||||||
|
var sql = "SELECT COALESCE(IA.parentItemID, itemID) AS itemID FROM items "
|
||||||
|
+ "LEFT JOIN itemAnnotations IA USING (itemID)";
|
||||||
|
|
||||||
var sqlParams = [];
|
var sqlParams = [];
|
||||||
// Separate ANY conditions for 'required' condition support
|
// Separate ANY conditions for 'required' condition support
|
||||||
var anySQL = '';
|
var anySQL = '';
|
||||||
|
|
@ -962,7 +966,8 @@ Zotero.Search.prototype._buildQuery = Zotero.Promise.coroutine(function* () {
|
||||||
let conditionData = Zotero.SearchConditions.get(name);
|
let conditionData = Zotero.SearchConditions.get(name);
|
||||||
|
|
||||||
// Has a table (or 'savedSearch', which doesn't have a table but isn't special)
|
// Has a table (or 'savedSearch', which doesn't have a table but isn't special)
|
||||||
if (conditionData.table || name == 'savedSearch' || name == 'tempTable') {
|
// TEMP: Or 'tag', which needs to match annotation parents
|
||||||
|
if (conditionData.table || name == 'savedSearch' || name == 'tempTable' || name == 'tag') {
|
||||||
// For conditions with an inline filter using 'is'/'isNot', combine with last condition
|
// For conditions with an inline filter using 'is'/'isNot', combine with last condition
|
||||||
// if the same
|
// if the same
|
||||||
if (lastCondition
|
if (lastCondition
|
||||||
|
|
@ -1077,14 +1082,15 @@ Zotero.Search.prototype._buildQuery = Zotero.Promise.coroutine(function* () {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unfiled) {
|
if (unfiled) {
|
||||||
sql += " AND (itemID NOT IN (SELECT itemID FROM collectionItems) "
|
sql += " AND (itemID NOT IN ("
|
||||||
|
+ "SELECT itemID FROM collectionItems "
|
||||||
// Exclude children
|
// Exclude children
|
||||||
+ "AND itemID NOT IN "
|
+ "UNION SELECT itemID FROM itemAttachments WHERE parentItemID IS NOT NULL "
|
||||||
+ "(SELECT itemID FROM itemAttachments WHERE parentItemID IS NOT NULL "
|
+ "UNION SELECT itemID FROM itemNotes WHERE parentItemID IS NOT NULL "
|
||||||
+ "UNION SELECT itemID FROM itemNotes WHERE parentItemID IS NOT NULL)"
|
+ "UNION SELECT itemID FROM itemAnnotations "
|
||||||
+ ") "
|
|
||||||
// Exclude My Publications
|
// Exclude My Publications
|
||||||
+ "AND itemID NOT IN (SELECT itemID FROM publicationsItems)";
|
+ "UNION SELECT itemID FROM publicationsItems "
|
||||||
|
+ "))";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (retracted) {
|
if (retracted) {
|
||||||
|
|
@ -1119,22 +1125,42 @@ Zotero.Search.prototype._buildQuery = Zotero.Promise.coroutine(function* () {
|
||||||
//
|
//
|
||||||
// Special table handling
|
// Special table handling
|
||||||
//
|
//
|
||||||
if (condition['table']){
|
if (condition.table) {
|
||||||
switch (condition['table']){
|
let negationOperators = ['isNot', 'doesNotContain'];
|
||||||
default:
|
let isNegationOperator = negationOperators.includes(condition.operator);
|
||||||
condSelectSQL += 'itemID '
|
|
||||||
switch (condition['operator']){
|
condSelectSQL += 'itemID '
|
||||||
case 'isNot':
|
if (isNegationOperator) {
|
||||||
case 'doesNotContain':
|
condSelectSQL += 'NOT ';
|
||||||
condSelectSQL += 'NOT ';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
condSelectSQL += 'IN (';
|
|
||||||
selectOpenParens = 1;
|
|
||||||
condSQL += 'SELECT itemID FROM ' +
|
|
||||||
condition['table'] + ' WHERE (';
|
|
||||||
openParens = 1;
|
|
||||||
}
|
}
|
||||||
|
condSelectSQL += 'IN (';
|
||||||
|
selectOpenParens = 1;
|
||||||
|
|
||||||
|
// TEMP: Don't match annotations for negation operators, since it would result in
|
||||||
|
// all parent attachments being returned
|
||||||
|
if (isNegationOperator) {
|
||||||
|
condSelectSQL += "SELECT itemID FROM items WHERE itemTypeID="
|
||||||
|
+ Zotero.ItemTypes.getID('annotation') + " UNION ";
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (condition.name) {
|
||||||
|
// TEMP: Match parent attachments of matching annotations
|
||||||
|
case 'tag':
|
||||||
|
condSQL += "SELECT COALESCE(IAnT.parentItemID, itemID) FROM itemTags "
|
||||||
|
+ "LEFT JOIN itemAnnotations IAnT USING (itemID) WHERE (";
|
||||||
|
break;
|
||||||
|
|
||||||
|
// TEMP: Match parent attachments of matching annotations
|
||||||
|
case 'annotationText':
|
||||||
|
case 'annotationComment':
|
||||||
|
condSQL += `SELECT parentItemID FROM ${condition.table} WHERE (`
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
condSQL += `SELECT itemID FROM ${condition.table} WHERE (`;
|
||||||
|
}
|
||||||
|
|
||||||
|
openParens = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -1709,7 +1735,11 @@ Zotero.Search.prototype._buildQuery = Zotero.Promise.coroutine(function* () {
|
||||||
|
|
||||||
// Add on quicksearch conditions
|
// Add on quicksearch conditions
|
||||||
if (quicksearchSQLSet) {
|
if (quicksearchSQLSet) {
|
||||||
sql = "SELECT itemID FROM items WHERE itemID IN (" + sql + ") "
|
// TEMP: Match parent attachments for annotations
|
||||||
|
//sql = "SELECT itemID FROM items WHERE itemID IN (" + sql + ") "
|
||||||
|
sql = "SELECT COALESCE(IAn.parentItemID, itemID) AS itemID FROM items "
|
||||||
|
+ "LEFT JOIN itemAnnotations IAn USING (itemID) "
|
||||||
|
+ "WHERE itemID IN (" + sql + ") "
|
||||||
+ "AND ((" + quicksearchSQLSet.join(') AND (') + "))";
|
+ "AND ((" + quicksearchSQLSet.join(') AND (') + "))";
|
||||||
|
|
||||||
for (var k=0; k<quicksearchParamsSet.length; k++) {
|
for (var k=0; k<quicksearchParamsSet.length; k++) {
|
||||||
|
|
|
||||||
|
|
@ -163,9 +163,6 @@ Zotero.Tags = new function() {
|
||||||
if (libraryID) {
|
if (libraryID) {
|
||||||
sql += "JOIN items USING (itemID) WHERE libraryID = ? ";
|
sql += "JOIN items USING (itemID) WHERE libraryID = ? ";
|
||||||
params.push(libraryID);
|
params.push(libraryID);
|
||||||
// TEMP: Don't show annotation tags in tag selector
|
|
||||||
sql += "AND itemTypeID != ? ";
|
|
||||||
params.push(Zotero.ItemTypes.getID('annotation'));
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sql += "WHERE 1 ";
|
sql += "WHERE 1 ";
|
||||||
|
|
@ -174,7 +171,11 @@ Zotero.Tags = new function() {
|
||||||
if (libraryID) {
|
if (libraryID) {
|
||||||
throw new Error("tmpTable and libraryID are mutually exclusive");
|
throw new Error("tmpTable and libraryID are mutually exclusive");
|
||||||
}
|
}
|
||||||
sql += "AND itemID IN (SELECT itemID FROM " + tmpTable + ") ";
|
sql += "AND itemID IN (SELECT itemID FROM " + tmpTable;
|
||||||
|
// TEMP: Match parent attachments for annotation tags
|
||||||
|
sql += " UNION SELECT itemID FROM itemAnnotations WHERE parentItemID IN "
|
||||||
|
+ "(SELECT itemID FROM " + tmpTable + ")";
|
||||||
|
sql += ") ";
|
||||||
}
|
}
|
||||||
if (types && types.length) {
|
if (types && types.length) {
|
||||||
sql += "AND type IN (" + new Array(types.length).fill('?').join(', ') + ") ";
|
sql += "AND type IN (" + new Array(types.length).fill('?').join(', ') + ") ";
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@
|
||||||
|
|
||||||
Components.utils.import("resource://gre/modules/InlineSpellChecker.jsm");
|
Components.utils.import("resource://gre/modules/InlineSpellChecker.jsm");
|
||||||
|
|
||||||
|
import FilePicker from 'zotero/modules/filePicker';
|
||||||
|
|
||||||
// Note: TinyMCE is automatically doing some meaningless corrections to
|
// Note: TinyMCE is automatically doing some meaningless corrections to
|
||||||
// note-editor produced HTML. Which might result to more
|
// note-editor produced HTML. Which might result to more
|
||||||
// conflicts, especially in group libraries
|
// conflicts, especially in group libraries
|
||||||
|
|
@ -43,9 +45,6 @@ const DOWNLOADED_IMAGE_TYPE = [
|
||||||
'image/png'
|
'image/png'
|
||||||
];
|
];
|
||||||
|
|
||||||
// Schema version here has to be the same as in note-editor!
|
|
||||||
const SCHEMA_VERSION = 8;
|
|
||||||
|
|
||||||
class EditorInstance {
|
class EditorInstance {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.instanceID = Zotero.Utilities.randomString();
|
this.instanceID = Zotero.Utilities.randomString();
|
||||||
|
|
@ -89,6 +88,76 @@ class EditorInstance {
|
||||||
return doc.execCommand(command, ui, value);
|
return doc.execCommand(command, ui, value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Translate note HTML into Markdown, for setting it as text/plain in clipboard (on text copy/drag)
|
||||||
|
this._iframeWindow.wrappedJSObject.zoteroTranslateToMarkdown = (html) => {
|
||||||
|
let item = new Zotero.Item('note');
|
||||||
|
item.libraryID = this._item.libraryID;
|
||||||
|
item.setNote(html);
|
||||||
|
let text = '';
|
||||||
|
var translation = new Zotero.Translate.Export;
|
||||||
|
translation.noWait = true;
|
||||||
|
translation.setItems([item]);
|
||||||
|
translation.setTranslator(Zotero.Translators.TRANSLATOR_ID_NOTE_MARKDOWN);
|
||||||
|
translation.setHandler("done", (obj, worked) => {
|
||||||
|
if (worked) {
|
||||||
|
text = obj.string.replace(/\r\n/g, '\n');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
translation.translate();
|
||||||
|
return text;
|
||||||
|
};
|
||||||
|
|
||||||
|
this._iframeWindow.wrappedJSObject.zoteroCopyImage = async (dataURL) => {
|
||||||
|
let parts = dataURL.split(',');
|
||||||
|
if (!parts[0].includes('base64')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let mime = parts[0].match(/:(.*?);/)[1];
|
||||||
|
let bstr = atob(parts[1]);
|
||||||
|
let n = bstr.length;
|
||||||
|
let u8arr = new Uint8Array(n);
|
||||||
|
while (n--) {
|
||||||
|
u8arr[n] = bstr.charCodeAt(n);
|
||||||
|
}
|
||||||
|
let imgTools = Components.classes["@mozilla.org/image/tools;1"]
|
||||||
|
.getService(Components.interfaces.imgITools);
|
||||||
|
let transferable = Components.classes['@mozilla.org/widget/transferable;1']
|
||||||
|
.createInstance(Components.interfaces.nsITransferable);
|
||||||
|
let clipboardService = Components.classes['@mozilla.org/widget/clipboard;1']
|
||||||
|
.getService(Components.interfaces.nsIClipboard);
|
||||||
|
let imgPtr = Components.classes["@mozilla.org/supports-interface-pointer;1"]
|
||||||
|
.createInstance(Components.interfaces.nsISupportsInterfacePointer);
|
||||||
|
imgPtr.data = imgTools.decodeImageFromArrayBuffer(u8arr.buffer, mime);
|
||||||
|
transferable.init(null);
|
||||||
|
transferable.addDataFlavor(mime);
|
||||||
|
transferable.setTransferData(mime, imgPtr, 0);
|
||||||
|
clipboardService.setData(transferable, null, Components.interfaces.nsIClipboard.kGlobalClipboard);
|
||||||
|
};
|
||||||
|
|
||||||
|
this._iframeWindow.wrappedJSObject.zoteroSaveImageAs = async (dataURL) => {
|
||||||
|
let parts = dataURL.split(',');
|
||||||
|
if (!parts[0].includes('base64')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let mime = parts[0].match(/:(.*?);/)[1];
|
||||||
|
let bstr = atob(parts[1]);
|
||||||
|
let n = bstr.length;
|
||||||
|
let u8arr = new Uint8Array(n);
|
||||||
|
while (n--) {
|
||||||
|
u8arr[n] = bstr.charCodeAt(n);
|
||||||
|
}
|
||||||
|
let ext = Zotero.MIME.getPrimaryExtension(mime, '');
|
||||||
|
let fp = new FilePicker();
|
||||||
|
fp.init(this._iframeWindow, Zotero.getString('noteEditor.saveImageAs'), fp.modeSave);
|
||||||
|
fp.appendFilters(fp.filterImages);
|
||||||
|
fp.defaultString = Zotero.getString('fileTypes.image').toLowerCase() + '.' + ext;
|
||||||
|
let rv = await fp.show();
|
||||||
|
if (rv === fp.returnOK || rv === fp.returnReplace) {
|
||||||
|
let outputPath = fp.file;
|
||||||
|
await OS.File.writeAtomic(outputPath, u8arr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
this._iframeWindow.addEventListener('message', this._messageHandler);
|
this._iframeWindow.addEventListener('message', this._messageHandler);
|
||||||
this._iframeWindow.addEventListener('error', (event) => {
|
this._iframeWindow.addEventListener('error', (event) => {
|
||||||
Zotero.logError(event.error);
|
Zotero.logError(event.error);
|
||||||
|
|
@ -697,6 +766,9 @@ class EditorInstance {
|
||||||
}
|
}
|
||||||
menuitem.setAttribute('checked', item.checked);
|
menuitem.setAttribute('checked', item.checked);
|
||||||
menuitem.addEventListener('command', () => {
|
menuitem.addEventListener('command', () => {
|
||||||
|
if (item.name === 'insertImage') {
|
||||||
|
return this._iframeWindow.eval('openImageFilePicker()');
|
||||||
|
}
|
||||||
this._postMessage({
|
this._postMessage({
|
||||||
action: 'contextMenuAction',
|
action: 'contextMenuAction',
|
||||||
ctxAction: item.name,
|
ctxAction: item.name,
|
||||||
|
|
@ -1193,10 +1265,12 @@ class EditorInstance {
|
||||||
* Create note from annotations
|
* Create note from annotations
|
||||||
*
|
*
|
||||||
* @param {Zotero.Item[]} annotations
|
* @param {Zotero.Item[]} annotations
|
||||||
* @param {Integer} parentID Creates standalone note if not provided
|
* @param {Object} options
|
||||||
|
* @param {Integer} options.parentID - Creates standalone note if not provided
|
||||||
|
* @param {Integer} options.collectionID - Only valid if parentID not provided
|
||||||
* @returns {Promise<Zotero.Item>}
|
* @returns {Promise<Zotero.Item>}
|
||||||
*/
|
*/
|
||||||
static async createNoteFromAnnotations(annotations, parentID) {
|
static async createNoteFromAnnotations(annotations, { parentID, collectionID } = {}) {
|
||||||
if (!annotations.length) {
|
if (!annotations.length) {
|
||||||
throw new Error("No annotations provided");
|
throw new Error("No annotations provided");
|
||||||
}
|
}
|
||||||
|
|
@ -1217,7 +1291,12 @@ class EditorInstance {
|
||||||
|
|
||||||
let note = new Zotero.Item('note');
|
let note = new Zotero.Item('note');
|
||||||
note.libraryID = annotations[0].libraryID;
|
note.libraryID = annotations[0].libraryID;
|
||||||
note.parentID = parentID;
|
if (parentID) {
|
||||||
|
note.parentID = parentID;
|
||||||
|
}
|
||||||
|
else if (collectionID) {
|
||||||
|
note.addToCollection(collectionID);
|
||||||
|
}
|
||||||
await note.saveTx();
|
await note.saveTx();
|
||||||
let editorInstance = new EditorInstance();
|
let editorInstance = new EditorInstance();
|
||||||
editorInstance._item = note;
|
editorInstance._item = note;
|
||||||
|
|
@ -1239,10 +1318,61 @@ class EditorInstance {
|
||||||
html += '\n';
|
html += '\n';
|
||||||
|
|
||||||
await editorInstance.importImages(jsonAnnotations);
|
await editorInstance.importImages(jsonAnnotations);
|
||||||
let { html: serializedHTML, citationItems } = Zotero.EditorInstanceUtilities.serializeAnnotations(jsonAnnotations, true);
|
|
||||||
html += serializedHTML;
|
let multipleParentParent = false;
|
||||||
|
let lastParentParentID;
|
||||||
|
let lastParentID;
|
||||||
|
// Group annotations per attachment
|
||||||
|
let groups = [];
|
||||||
|
for (let i = 0; i < annotations.length; i++) {
|
||||||
|
let annotation = annotations[i];
|
||||||
|
let jsonAnnotation = jsonAnnotations[i];
|
||||||
|
let parentParentID = annotation.parentItem.parentID;
|
||||||
|
let parentID = annotation.parentID;
|
||||||
|
if (groups.length) {
|
||||||
|
if (parentParentID !== lastParentParentID) {
|
||||||
|
// Multiple top level regular items detected, allow including their titles
|
||||||
|
multipleParentParent = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!groups.length || parentID !== lastParentID) {
|
||||||
|
groups.push({
|
||||||
|
parentTitle: annotation.parentItem.getDisplayTitle(),
|
||||||
|
parentParentID,
|
||||||
|
parentParentTitle: annotation.parentItem.parentItem && annotation.parentItem.parentItem.getDisplayTitle(),
|
||||||
|
jsonAnnotations: [jsonAnnotation]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let group = groups[groups.length - 1];
|
||||||
|
group.jsonAnnotations.push(jsonAnnotation);
|
||||||
|
}
|
||||||
|
lastParentParentID = parentParentID;
|
||||||
|
lastParentID = parentID;
|
||||||
|
}
|
||||||
|
let citationItems = [];
|
||||||
|
lastParentParentID = null;
|
||||||
|
for (let group of groups) {
|
||||||
|
if (multipleParentParent && group.parentParentTitle && lastParentParentID !== group.parentParentID) {
|
||||||
|
html += `<h2>${group.parentParentTitle}</h2>\n`;
|
||||||
|
}
|
||||||
|
lastParentParentID = group.parentParentID;
|
||||||
|
// If attachment doesn't have a parent or there are more attachments with the same parent, show attachment title
|
||||||
|
if (!group.parentParentID || groups.filter(x => x.parentParentID === group.parentParentID).length > 1) {
|
||||||
|
html += `<h3>${group.parentTitle}</h3>\n`;
|
||||||
|
}
|
||||||
|
let { html: _html, citationItems: _citationItems } = Zotero.EditorInstanceUtilities.serializeAnnotations(group.jsonAnnotations, true);
|
||||||
|
html += _html + '\n';
|
||||||
|
for (let _citationItem of _citationItems) {
|
||||||
|
if (!citationItems.find(item => item.uris.some(uri => _citationItem.uris.includes(uri)))) {
|
||||||
|
citationItems.push(_citationItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
citationItems = encodeURIComponent(JSON.stringify(citationItems));
|
citationItems = encodeURIComponent(JSON.stringify(citationItems));
|
||||||
html = `<div data-citation-items="${citationItems}" data-schema-version="${SCHEMA_VERSION}">${html}</div>`;
|
// Note: Update schema version only if using new features
|
||||||
|
let schemaVersion = 8;
|
||||||
|
html = `<div data-citation-items="${citationItems}" data-schema-version="${schemaVersion}">${html}</div>`;
|
||||||
note.setNote(html);
|
note.setNote(html);
|
||||||
await note.saveTx();
|
await note.saveTx();
|
||||||
return note;
|
return note;
|
||||||
|
|
@ -1268,7 +1398,8 @@ class EditorInstanceUtilities {
|
||||||
|
|
||||||
if (!annotation.text
|
if (!annotation.text
|
||||||
&& !annotation.comment
|
&& !annotation.comment
|
||||||
&& !annotation.imageAttachmentKey) {
|
&& !annotation.imageAttachmentKey
|
||||||
|
|| annotation.type === 'ink') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1359,16 +1490,24 @@ class EditorInstanceUtilities {
|
||||||
template = '<p>{{image}}<br/>{{citation}} {{comment}}</p>';
|
template = '<p>{{image}}<br/>{{citation}} {{comment}}</p>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Zotero.debug('Using note template:');
|
||||||
|
Zotero.debug(template);
|
||||||
|
|
||||||
|
template = template.replace(
|
||||||
|
/(<blockquote>[^<>]*?)({{highlight}})([\s\S]*?<\/blockquote>)/g,
|
||||||
|
(match, p1, p2, p3) => p1 + "{{highlight quotes='false'}}" + p3
|
||||||
|
);
|
||||||
|
|
||||||
let vars = {
|
let vars = {
|
||||||
color: annotation.color || '',
|
color: annotation.color || '',
|
||||||
highlight: (attrs) => attrs.quotes === 'true' ? quotedHighlightHTML : highlightHTML,
|
// Include quotation marks by default, but allow to disable with `quotes='false'`
|
||||||
|
highlight: (attrs) => attrs.quotes === 'false' ? highlightHTML : quotedHighlightHTML,
|
||||||
comment: commentHTML,
|
comment: commentHTML,
|
||||||
citation: citationHTML,
|
citation: citationHTML,
|
||||||
image: imageHTML,
|
image: imageHTML,
|
||||||
tags: (attrs) => (annotation.tags && annotation.tags.map(tag => tag.name) || []).join(attrs.join || ' ')
|
tags: (attrs) => (annotation.tags && annotation.tags.map(tag => tag.name) || []).join(attrs.join || ' ')
|
||||||
};
|
};
|
||||||
Zotero.debug('Using note template:');
|
|
||||||
Zotero.debug(template);
|
|
||||||
let templateHTML = Zotero.Utilities.Internal.generateHTMLFromTemplate(template, vars);
|
let templateHTML = Zotero.Utilities.Internal.generateHTMLFromTemplate(template, vars);
|
||||||
// Remove some spaces at the end of paragraph
|
// Remove some spaces at the end of paragraph
|
||||||
templateHTML = templateHTML.replace(/([\s]*)(<\/p)/g, '$2');
|
templateHTML = templateHTML.replace(/([\s]*)(<\/p)/g, '$2');
|
||||||
|
|
@ -1529,5 +1668,4 @@ class EditorInstanceUtilities {
|
||||||
}
|
}
|
||||||
|
|
||||||
Zotero.EditorInstance = EditorInstance;
|
Zotero.EditorInstance = EditorInstance;
|
||||||
Zotero.EditorInstance.SCHEMA_VERSION = SCHEMA_VERSION;
|
|
||||||
Zotero.EditorInstanceUtilities = new EditorInstanceUtilities();
|
Zotero.EditorInstanceUtilities = new EditorInstanceUtilities();
|
||||||
|
|
|
||||||
|
|
@ -1086,7 +1086,31 @@ Zotero.File = new function(){
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize to a Unix-style path, replacing backslashes (interpreted as
|
||||||
|
* separators only on Windows) with forward slashes (interpreted as
|
||||||
|
* separators everywhere)
|
||||||
|
*
|
||||||
|
* @param {String} path
|
||||||
|
* @return {String}
|
||||||
|
*/
|
||||||
|
this.normalizeToUnix = function (path) {
|
||||||
|
// If we're on Windows, we need to normalize first and then replace
|
||||||
|
// the slashes, because OS.Path.normalize won't handle forward slashes
|
||||||
|
// correctly. Otherwise, we replace slashes first and *then* normalize.
|
||||||
|
// This should ensure consistent behavior across platforms.
|
||||||
|
if (Zotero.isWin) {
|
||||||
|
let normalized = OS.Path.normalize(path);
|
||||||
|
return normalized.replace(/\\/g, '/');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let replaced = path.replace(/\\/g, '/');
|
||||||
|
return OS.Path.normalize(replaced);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1096,8 +1120,8 @@ Zotero.File = new function(){
|
||||||
if (typeof dir != 'string') throw new Error("dir must be a string");
|
if (typeof dir != 'string') throw new Error("dir must be a string");
|
||||||
if (typeof file != 'string') throw new Error("file must be a string");
|
if (typeof file != 'string') throw new Error("file must be a string");
|
||||||
|
|
||||||
dir = OS.Path.normalize(dir).replace(/\\/g, "/");
|
dir = this.normalizeToUnix(dir);
|
||||||
file = OS.Path.normalize(file).replace(/\\/g, "/");
|
file = this.normalizeToUnix(file);
|
||||||
// Normalize D:\ vs. D:\foo
|
// Normalize D:\ vs. D:\foo
|
||||||
if (dir != file && !dir.endsWith('/')) {
|
if (dir != file && !dir.endsWith('/')) {
|
||||||
dir += '/';
|
dir += '/';
|
||||||
|
|
|
||||||
|
|
@ -381,8 +381,8 @@ Zotero.Fulltext = Zotero.FullText = new function(){
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!charset) {
|
if (!charset) {
|
||||||
Zotero.logError(`Item ${itemID} didn't have a charset`);
|
Zotero.debug(`Item ${itemID} doesn't have a charset set -- using 'utf-8'`);
|
||||||
return false;
|
charset = 'utf-8';
|
||||||
}
|
}
|
||||||
|
|
||||||
var maxLength = Zotero.Prefs.get('fulltext.textMaxLength');
|
var maxLength = Zotero.Prefs.get('fulltext.textMaxLength');
|
||||||
|
|
|
||||||
|
|
@ -166,46 +166,48 @@ Zotero.HTTP = new function() {
|
||||||
if (e.xmlhttp.status == 503 && await _checkRetry(e.xmlhttp)) {
|
if (e.xmlhttp.status == 503 && await _checkRetry(e.xmlhttp)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// Don't retry if errorDelayMax is 0
|
||||||
|
if (options.errorDelayMax === 0) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
// Automatically retry other 5xx errors by default
|
// Automatically retry other 5xx errors by default
|
||||||
if (options.errorDelayMax !== 0) {
|
if (!errorDelayGenerator) {
|
||||||
if (!errorDelayGenerator) {
|
// Keep trying for up to an hour
|
||||||
// Keep trying for up to an hour
|
errorDelayGenerator = Zotero.Utilities.Internal.delayGenerator(
|
||||||
errorDelayGenerator = Zotero.Utilities.Internal.delayGenerator(
|
options.errorDelayIntervals || _errorDelayIntervals,
|
||||||
options.errorDelayIntervals || _errorDelayIntervals,
|
options.errorDelayMax !== undefined
|
||||||
options.errorDelayMax !== undefined
|
? options.errorDelayMax
|
||||||
? options.errorDelayMax
|
: _errorDelayMax
|
||||||
: _errorDelayMax
|
);
|
||||||
);
|
}
|
||||||
|
let delayPromise = errorDelayGenerator.next().value;
|
||||||
|
let keepGoing;
|
||||||
|
// Provide caller with a callback to cancel while waiting to retry
|
||||||
|
if (options.cancellerReceiver) {
|
||||||
|
let resolve;
|
||||||
|
let reject;
|
||||||
|
let cancelPromise = new Zotero.Promise((res, rej) => {
|
||||||
|
resolve = res;
|
||||||
|
reject = function () {
|
||||||
|
rej(new Zotero.HTTP.CancelledException);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
options.cancellerReceiver(reject);
|
||||||
|
try {
|
||||||
|
keepGoing = await Promise.race([delayPromise, cancelPromise]);
|
||||||
}
|
}
|
||||||
let delayPromise = errorDelayGenerator.next().value;
|
catch (e) {
|
||||||
let keepGoing;
|
Zotero.debug("Request cancelled");
|
||||||
// Provide caller with a callback to cancel while waiting to retry
|
|
||||||
if (options.cancellerReceiver) {
|
|
||||||
let resolve;
|
|
||||||
let reject;
|
|
||||||
let cancelPromise = new Zotero.Promise((res, rej) => {
|
|
||||||
resolve = res;
|
|
||||||
reject = function () {
|
|
||||||
rej(new Zotero.HTTP.CancelledException);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
options.cancellerReceiver(reject);
|
|
||||||
try {
|
|
||||||
keepGoing = await Promise.race([delayPromise, cancelPromise]);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
Zotero.debug("Request cancelled");
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
keepGoing = await delayPromise;
|
|
||||||
}
|
|
||||||
if (!keepGoing) {
|
|
||||||
Zotero.logError("Failed too many times");
|
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
keepGoing = await delayPromise;
|
||||||
|
}
|
||||||
|
if (!keepGoing) {
|
||||||
|
Zotero.logError("Failed too many times");
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -1217,9 +1219,10 @@ Zotero.HTTP = new function() {
|
||||||
* @param {Boolean} dontDelete Don't delete the hidden browser upon completion; calling function
|
* @param {Boolean} dontDelete Don't delete the hidden browser upon completion; calling function
|
||||||
* must call deleteHiddenBrowser itself.
|
* must call deleteHiddenBrowser itself.
|
||||||
* @param {Zotero.CookieSandbox} [cookieSandbox] Cookie sandbox object
|
* @param {Zotero.CookieSandbox} [cookieSandbox] Cookie sandbox object
|
||||||
|
* @param {Object} [docShellPrefs] See Zotero.Browser.createHiddenBrowser
|
||||||
* @return {browser} Hidden browser used for loading
|
* @return {browser} Hidden browser used for loading
|
||||||
*/
|
*/
|
||||||
this.loadDocuments = function (urls, processor, onDone, onError, dontDelete, cookieSandbox) {
|
this.loadDocuments = function (urls, processor, onDone, onError, dontDelete, cookieSandbox, docShellPrefs={}) {
|
||||||
// (Approximately) how many seconds to wait if the document is left in the loading state and
|
// (Approximately) how many seconds to wait if the document is left in the loading state and
|
||||||
// pageshow is called before we call pageshow with an incomplete document
|
// pageshow is called before we call pageshow with an incomplete document
|
||||||
const LOADING_STATE_TIMEOUT = 120;
|
const LOADING_STATE_TIMEOUT = 120;
|
||||||
|
|
@ -1342,6 +1345,9 @@ Zotero.HTTP = new function() {
|
||||||
currentURL = 0;
|
currentURL = 0;
|
||||||
for(var i=0; i<urls.length; i++) {
|
for(var i=0; i<urls.length; i++) {
|
||||||
let hiddenBrowser = Zotero.Browser.createHiddenBrowser();
|
let hiddenBrowser = Zotero.Browser.createHiddenBrowser();
|
||||||
|
for (let pref in docShellPrefs) {
|
||||||
|
hiddenBrowser.docShell[pref] = docShellPrefs[pref];
|
||||||
|
}
|
||||||
if (cookieSandbox) {
|
if (cookieSandbox) {
|
||||||
cookieSandbox.attachToBrowser(hiddenBrowser);
|
cookieSandbox.attachToBrowser(hiddenBrowser);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -798,7 +798,8 @@ Zotero.Integration.Interface.prototype.addEditBibliography = Zotero.Promise.coro
|
||||||
* @return {Promise}
|
* @return {Promise}
|
||||||
*/
|
*/
|
||||||
Zotero.Integration.Interface.prototype.refresh = async function() {
|
Zotero.Integration.Interface.prototype.refresh = async function() {
|
||||||
await this._session.init(true, false)
|
await this._session.init(true, false);
|
||||||
|
this._session.shouldMerge = true;
|
||||||
|
|
||||||
this._session.reload = this._session.reload || this._session.data.prefs.delayCitationUpdates;
|
this._session.reload = this._session.reload || this._session.data.prefs.delayCitationUpdates;
|
||||||
await this._session.updateFromDocument(FORCE_CITATIONS_REGENERATE);
|
await this._session.updateFromDocument(FORCE_CITATIONS_REGENERATE);
|
||||||
|
|
@ -1037,6 +1038,10 @@ Zotero.Integration.Session.prototype.updateFromDocument = Zotero.Promise.corouti
|
||||||
this.progressBar.start();
|
this.progressBar.start();
|
||||||
if (forceCitations) {
|
if (forceCitations) {
|
||||||
this.regenAll = true;
|
this.regenAll = true;
|
||||||
|
// See Session.restoreProcessorState() for a comment
|
||||||
|
if (!Zotero.Prefs.get('cite.useCiteprocRs')) {
|
||||||
|
this.reload = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
yield this._processFields();
|
yield this._processFields();
|
||||||
try {
|
try {
|
||||||
|
|
@ -1068,6 +1073,7 @@ Zotero.Integration.Session.prototype._processFields = async function () {
|
||||||
throw new Error("_processFields called without fetching fields first");
|
throw new Error("_processFields called without fetching fields first");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let adjacentCitations = [];
|
||||||
for (var i = 0; i < this._fields.length; i++) {
|
for (var i = 0; i < this._fields.length; i++) {
|
||||||
let field = await Zotero.Integration.Field.loadExisting(this._fields[i]);
|
let field = await Zotero.Integration.Field.loadExisting(this._fields[i]);
|
||||||
if (field.type === INTEGRATION_TYPE_ITEM) {
|
if (field.type === INTEGRATION_TYPE_ITEM) {
|
||||||
|
|
@ -1075,7 +1081,15 @@ Zotero.Integration.Session.prototype._processFields = async function () {
|
||||||
data = await field.unserialize(),
|
data = await field.unserialize(),
|
||||||
citation = new Zotero.Integration.Citation(field, data, noteIndex);
|
citation = new Zotero.Integration.Citation(field, data, noteIndex);
|
||||||
|
|
||||||
await this.addCitation(i, noteIndex, citation);
|
if (this.shouldMerge && typeof field.isAdjacentToNextField === 'function' && await field.isAdjacentToNextField()) {
|
||||||
|
adjacentCitations.push(citation);
|
||||||
|
this._deleteFields[i] = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
await this.addCitation(i, noteIndex, citation, adjacentCitations);
|
||||||
|
if (adjacentCitations.length) {
|
||||||
|
adjacentCitations = [];
|
||||||
|
}
|
||||||
} else if (field.type === INTEGRATION_TYPE_BIBLIOGRAPHY) {
|
} else if (field.type === INTEGRATION_TYPE_BIBLIOGRAPHY) {
|
||||||
if (this.ignoreEmptyBibliography && (await field.getText()).trim() === "") {
|
if (this.ignoreEmptyBibliography && (await field.getText()).trim() === "") {
|
||||||
this._removeCodeFields[i] = true;
|
this._removeCodeFields[i] = true;
|
||||||
|
|
@ -1957,9 +1971,17 @@ Zotero.Integration.Session.prototype.importDocument = async function() {
|
||||||
/**
|
/**
|
||||||
* Adds a citation to the arrays representing the document
|
* Adds a citation to the arrays representing the document
|
||||||
*/
|
*/
|
||||||
Zotero.Integration.Session.prototype.addCitation = async function (index, noteIndex, citation) {
|
Zotero.Integration.Session.prototype.addCitation = async function (index, noteIndex, citation, adjacentCitations=[]) {
|
||||||
index = parseInt(index, 10);
|
index = parseInt(index, 10);
|
||||||
|
|
||||||
|
if (adjacentCitations.length) {
|
||||||
|
Zotero.debug(`Merging adjacent citations ${adjacentCitations.map(c => c.citationID)} to citation ${citation.citationID}`);
|
||||||
|
for (let adjacentCitation of adjacentCitations) {
|
||||||
|
citation.mergeCitation(adjacentCitation);
|
||||||
|
}
|
||||||
|
this.updateIndices[index] = true;
|
||||||
|
}
|
||||||
|
|
||||||
var action = await citation.loadItemData();
|
var action = await citation.loadItemData();
|
||||||
|
|
||||||
if (action == Zotero.Integration.REMOVE_CODE) {
|
if (action == Zotero.Integration.REMOVE_CODE) {
|
||||||
|
|
@ -2157,6 +2179,12 @@ Zotero.Integration.Session.prototype.restoreProcessorState = function() {
|
||||||
citations.push(this.citationsByIndex[i]);
|
citations.push(this.citationsByIndex[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!Zotero.Prefs.get('cite.useCiteprocRs')) {
|
||||||
|
// Due to a bug in citeproc-js there are disambiguation issues after changing items in Zotero library
|
||||||
|
// and rebuilding the processor state, so we reinitialize the processor altogether
|
||||||
|
let style = Zotero.Styles.get(this.data.style.styleID);
|
||||||
|
this.style = style.getCiteProc(this.data.style.locale, this.outputFormat, this.data.prefs.automaticJournalAbbreviations);
|
||||||
|
}
|
||||||
this.style.rebuildProcessorState(citations, this.outputFormat, uncited);
|
this.style.rebuildProcessorState(citations, this.outputFormat, uncited);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2623,7 +2651,7 @@ Zotero.Integration.Field = class {
|
||||||
throw new Error("Trying to instantiate Integration.Field with Integration.Field, not doc field");
|
throw new Error("Trying to instantiate Integration.Field with Integration.Field, not doc field");
|
||||||
}
|
}
|
||||||
for (let func of Zotero.Integration.Field.INTERFACE) {
|
for (let func of Zotero.Integration.Field.INTERFACE) {
|
||||||
if (!(func in this)) {
|
if (!(func in this) && (func in field)) {
|
||||||
this[func] = field[func].bind(field);
|
this[func] = field[func].bind(field);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2682,7 +2710,7 @@ Zotero.Integration.Field = class {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Zotero.Integration.Field.INTERFACE = ['delete', 'removeCode', 'select', 'setText',
|
Zotero.Integration.Field.INTERFACE = ['delete', 'removeCode', 'select', 'setText',
|
||||||
'getText', 'setCode', 'getCode', 'equals', 'getNoteIndex'];
|
'getText', 'setCode', 'getCode', 'equals', 'getNoteIndex', 'isAdjacentToNextField'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load existing field in document and return correct instance of field type
|
* Load existing field in document and return correct instance of field type
|
||||||
|
|
@ -2921,6 +2949,23 @@ Zotero.Integration.Citation = class {
|
||||||
this._field = citationField;
|
this._field = citationField;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge citation items and remove duplicates, unless the items have different
|
||||||
|
* @param citation {Citation}
|
||||||
|
*/
|
||||||
|
mergeCitation(citation) {
|
||||||
|
let items = this.citationItems.concat(citation.citationItems);
|
||||||
|
let addedItems = new Set();
|
||||||
|
this.citationItems = []
|
||||||
|
for (let item of items) {
|
||||||
|
if (addedItems.has(item.id)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
addedItems.add(item.id);
|
||||||
|
this.citationItems.push(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load citation item data
|
* Load citation item data
|
||||||
* @param {Boolean} [promptToReselect=true] - will throw a MissingItemException if false
|
* @param {Boolean} [promptToReselect=true] - will throw a MissingItemException if false
|
||||||
|
|
|
||||||
|
|
@ -55,20 +55,22 @@ Zotero.MIMETypeHandler = new function () {
|
||||||
_observers = [];
|
_observers = [];
|
||||||
|
|
||||||
// Install styles from the Cite preferences
|
// Install styles from the Cite preferences
|
||||||
this.addHandler("application/vnd.citationstyles.style+xml", async function (blob, origin) {
|
this.addHandlers("application/vnd.citationstyles.style+xml", {
|
||||||
let win = Services.wm.getMostRecentWindow("zotero:basicViewer");
|
onContent: async function (blob, origin) {
|
||||||
var data = await Zotero.Utilities.Internal.blobToText(blob);
|
let win = Services.wm.getMostRecentWindow("zotero:basicViewer");
|
||||||
try {
|
var data = await Zotero.Utilities.Internal.blobToText(blob);
|
||||||
await Zotero.Styles.install(data, origin, true);
|
try {
|
||||||
}
|
await Zotero.Styles.install(data, origin, true);
|
||||||
catch (e) {
|
}
|
||||||
Zotero.logError(e);
|
catch (e) {
|
||||||
(new Zotero.Exception.Alert("styles.install.unexpectedError",
|
Zotero.logError(e);
|
||||||
origin, "styles.install.title", e)).present();
|
(new Zotero.Exception.Alert("styles.install.unexpectedError",
|
||||||
}
|
origin, "styles.install.title", e)).present();
|
||||||
// Close styles page in basic viewer after installing a style
|
}
|
||||||
if (win) {
|
// Close styles page in basic viewer after installing a style
|
||||||
win.close();
|
if (win) {
|
||||||
|
win.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, true);
|
}, true);
|
||||||
};
|
};
|
||||||
|
|
@ -76,17 +78,25 @@ Zotero.MIMETypeHandler = new function () {
|
||||||
/**
|
/**
|
||||||
* Adds a handler to handle a specific MIME type
|
* Adds a handler to handle a specific MIME type
|
||||||
* @param {String} type MIME type to handle
|
* @param {String} type MIME type to handle
|
||||||
* @param {Function} fn Function to call to handle type - fn(string, uri)
|
* @param {Object} handlers
|
||||||
|
* - handlers.onContent - function to call when content is received
|
||||||
|
* - handlers.onStartRequest - function to call when response for content type is first received
|
||||||
* @param {Boolean} ignoreContentDisposition If true, ignores the Content-Disposition header,
|
* @param {Boolean} ignoreContentDisposition If true, ignores the Content-Disposition header,
|
||||||
* which is often used to force a file to download rather than let it be handled by the web
|
* which is often used to force a file to download rather than let it be handled by the web
|
||||||
* browser
|
* browser
|
||||||
*/
|
*/
|
||||||
this.addHandler = function (type, fn, ignoreContentDisposition) {
|
this.addHandlers = function (type, handlers, ignoreContentDisposition) {
|
||||||
|
if (typeof handlers == 'function') {
|
||||||
|
handlers = {
|
||||||
|
onContent: handlers
|
||||||
|
};
|
||||||
|
Zotero.debug('MIMETypeHandler.addHandler: second parameter function is deprecated. Pass an object', 1)
|
||||||
|
}
|
||||||
if (_typeHandlers[type]) {
|
if (_typeHandlers[type]) {
|
||||||
_typeHandlers[type].push(fn);
|
_typeHandlers[type].push(handlers);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_typeHandlers[type] = [fn];
|
_typeHandlers[type] = [handlers];
|
||||||
}
|
}
|
||||||
if (ignoreContentDisposition) {
|
if (ignoreContentDisposition) {
|
||||||
_ignoreContentDispositionTypes.add(type);
|
_ignoreContentDispositionTypes.add(type);
|
||||||
|
|
@ -96,19 +106,19 @@ Zotero.MIMETypeHandler = new function () {
|
||||||
/**
|
/**
|
||||||
* Removes a handler for a specific MIME type
|
* Removes a handler for a specific MIME type
|
||||||
* @param {String} type MIME type to handle
|
* @param {String} type MIME type to handle
|
||||||
* @param {Function} handler Function handler to remove
|
* @param {Object} handlers Function handlers to remove
|
||||||
*/
|
*/
|
||||||
this.removeHandler = function (type, handler) {
|
this.removeHandlers = function (type, handlers) {
|
||||||
// If no handler specified or this is the last handler for the type
|
// If no handler specified or this is the last handler for the type
|
||||||
// stop monitoring the content type completely.
|
// stop monitoring the content type completely.
|
||||||
if (!handler || _typeHandlers[type] && _typeHandlers[type].length <= 1) {
|
if (!handlers || _typeHandlers[type] && _typeHandlers[type].length <= 1) {
|
||||||
delete _typeHandlers[type];
|
delete _typeHandlers[type];
|
||||||
_ignoreContentDispositionTypes.delete(type);
|
_ignoreContentDispositionTypes.delete(type);
|
||||||
}
|
}
|
||||||
else if (_typeHandlers[type]) {
|
else if (_typeHandlers[type]) {
|
||||||
var i = _typeHandlers[type].indexOf(handler);
|
var i = _typeHandlers[type].indexOf(handlers);
|
||||||
if (i != -1) {
|
if (i != -1) {
|
||||||
_typeHandlers.splice(i, 1);
|
_typeHandlers[type].splice(i, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -214,10 +224,27 @@ Zotero.MIMETypeHandler = new function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the request is started; we ignore this
|
* Called when the request is started
|
||||||
*/
|
*/
|
||||||
_StreamListener.prototype.onStartRequest = function(channel, context) {}
|
_StreamListener.prototype.onStartRequest = async function(channel, context) {
|
||||||
|
try {
|
||||||
|
if (!_typeHandlers[this._contentType]) return;
|
||||||
|
for (let handlers of _typeHandlers[this._contentType]) {
|
||||||
|
if (!handlers.onStartRequest) continue;
|
||||||
|
let maybePromise = handlers.onStartRequest(
|
||||||
|
this._request.name ? this._request.name : null,
|
||||||
|
this._contentType,
|
||||||
|
channel
|
||||||
|
);
|
||||||
|
if (maybePromise && maybePromise.then) {
|
||||||
|
maybePromise = await maybePromise;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
Zotero.logError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when there's data available; we collect this data and keep it until the request is
|
* Called when there's data available; we collect this data and keep it until the request is
|
||||||
|
|
@ -259,14 +286,16 @@ Zotero.MIMETypeHandler = new function () {
|
||||||
|
|
||||||
var handled = false;
|
var handled = false;
|
||||||
try {
|
try {
|
||||||
for (let handler of _typeHandlers[this._contentType]) {
|
if (!_typeHandlers[this._contentType]) return;
|
||||||
let maybePromise = handler(
|
for (let handlers of _typeHandlers[this._contentType]) {
|
||||||
|
if (!handlers.onContent) continue;
|
||||||
|
let maybePromise = handlers.onContent(
|
||||||
blob,
|
blob,
|
||||||
this._request.name ? this._request.name : null,
|
this._request.name ? this._request.name : null,
|
||||||
this._contentType,
|
this._contentType,
|
||||||
channel
|
channel
|
||||||
);
|
);
|
||||||
if (maybePromise.then) {
|
if (maybePromise && maybePromise.then) {
|
||||||
maybePromise = await maybePromise;
|
maybePromise = await maybePromise;
|
||||||
}
|
}
|
||||||
handled = handled || maybePromise;
|
handled = handled || maybePromise;
|
||||||
|
|
|
||||||
|
|
@ -271,6 +271,10 @@ class PDFWorker {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let path = await attachment.getFilePathAsync();
|
let path = await attachment.getFilePathAsync();
|
||||||
|
let fileSize = (await OS.File.stat(path)).size;
|
||||||
|
if (fileSize > Math.pow(2, 31) - 1) {
|
||||||
|
throw new Error(`The file "${path}" is too large`);
|
||||||
|
}
|
||||||
let buf = await OS.File.read(path, {});
|
let buf = await OS.File.read(path, {});
|
||||||
buf = new Uint8Array(buf).buffer;
|
buf = new Uint8Array(buf).buffer;
|
||||||
|
|
||||||
|
|
@ -341,6 +345,10 @@ class PDFWorker {
|
||||||
|
|
||||||
async processCitaviAnnotations(pdfPath, citaviAnnotations, isPriority, password) {
|
async processCitaviAnnotations(pdfPath, citaviAnnotations, isPriority, password) {
|
||||||
return this._enqueue(async () => {
|
return this._enqueue(async () => {
|
||||||
|
let fileSize = (await OS.File.stat(pdfPath)).size;
|
||||||
|
if (fileSize > Math.pow(2, 31) - 1) {
|
||||||
|
throw new Error(`The file "${pdfPath}" is too large`);
|
||||||
|
}
|
||||||
let buf = await OS.File.read(pdfPath, {});
|
let buf = await OS.File.read(pdfPath, {});
|
||||||
buf = new Uint8Array(buf).buffer;
|
buf = new Uint8Array(buf).buffer;
|
||||||
try {
|
try {
|
||||||
|
|
@ -371,6 +379,10 @@ class PDFWorker {
|
||||||
*/
|
*/
|
||||||
async processMendeleyAnnotations(pdfPath, mendeleyAnnotations, isPriority, password) {
|
async processMendeleyAnnotations(pdfPath, mendeleyAnnotations, isPriority, password) {
|
||||||
return this._enqueue(async () => {
|
return this._enqueue(async () => {
|
||||||
|
let fileSize = (await OS.File.stat(pdfPath)).size;
|
||||||
|
if (fileSize > Math.pow(2, 31) - 1) {
|
||||||
|
throw new Error(`The file "${pdfPath}" is too large`);
|
||||||
|
}
|
||||||
let buf = await OS.File.read(pdfPath, {});
|
let buf = await OS.File.read(pdfPath, {});
|
||||||
buf = new Uint8Array(buf).buffer;
|
buf = new Uint8Array(buf).buffer;
|
||||||
try {
|
try {
|
||||||
|
|
@ -410,6 +422,162 @@ class PDFWorker {
|
||||||
}
|
}
|
||||||
await Promise.all(promises);
|
await Promise.all(promises);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete pages from PDF attachment
|
||||||
|
*
|
||||||
|
* @param {Integer} itemID Attachment item id
|
||||||
|
* @param {Array} pageIndexes
|
||||||
|
* @param {Boolean} [isPriority]
|
||||||
|
* @param {String} [password]
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
async deletePages(itemID, pageIndexes, isPriority, password) {
|
||||||
|
return this._enqueue(async () => {
|
||||||
|
let attachment = await Zotero.Items.getAsync(itemID);
|
||||||
|
|
||||||
|
Zotero.debug(`Deleting [${pageIndexes.join(', ')}] pages for item ${attachment.libraryKey}`);
|
||||||
|
let t = new Date();
|
||||||
|
|
||||||
|
if (!attachment.isPDFAttachment()) {
|
||||||
|
throw new Error('Item must be a PDF attachment');
|
||||||
|
}
|
||||||
|
|
||||||
|
let annotations = attachment
|
||||||
|
.getAnnotations()
|
||||||
|
.map(annotation => ({
|
||||||
|
id: annotation.id,
|
||||||
|
position: JSON.parse(annotation.annotationPosition)
|
||||||
|
}));
|
||||||
|
|
||||||
|
let path = await attachment.getFilePathAsync();
|
||||||
|
let buf = await OS.File.read(path, {});
|
||||||
|
buf = new Uint8Array(buf).buffer;
|
||||||
|
|
||||||
|
try {
|
||||||
|
var { buf: modifiedBuf } = await this._query('deletePages', {
|
||||||
|
buf, pageIndexes, password
|
||||||
|
}, [buf]);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
let error = new Error(`Worker 'deletePages' failed: ${JSON.stringify({ error: e.message })}`);
|
||||||
|
try {
|
||||||
|
error.name = JSON.parse(e.message).name;
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
Zotero.logError(e);
|
||||||
|
}
|
||||||
|
Zotero.logError(error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete annotations from deleted pages
|
||||||
|
let ids = [];
|
||||||
|
for (let i = annotations.length - 1; i >= 0; i--) {
|
||||||
|
let { id, position } = annotations[i];
|
||||||
|
if (pageIndexes.includes(position.pageIndex)) {
|
||||||
|
ids.push(id);
|
||||||
|
annotations.splice(i, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ids.length) {
|
||||||
|
await Zotero.Items.erase(ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shift page index for other annotations
|
||||||
|
ids = [];
|
||||||
|
await Zotero.DB.executeTransaction(async function () {
|
||||||
|
let rows = await Zotero.DB.queryAsync('SELECT itemID, position FROM itemAnnotations WHERE parentItemID=?', itemID);
|
||||||
|
for (let { itemID, position } of rows) {
|
||||||
|
try {
|
||||||
|
position = JSON.parse(position);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
Zotero.logError(e);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Find the count of deleted pages before the current annotation page
|
||||||
|
let shift = pageIndexes.reduce((prev, cur) => cur < position.pageIndex ? prev + 1 : prev, 0);
|
||||||
|
if (shift > 0) {
|
||||||
|
position.pageIndex -= shift;
|
||||||
|
position = JSON.stringify(position);
|
||||||
|
await Zotero.DB.queryAsync('UPDATE itemAnnotations SET position=? WHERE itemID=?', [position, itemID]);
|
||||||
|
ids.push(itemID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let objectsClass = Zotero.DataObjectUtilities.getObjectsClassForObjectType('item');
|
||||||
|
let loadedObjects = objectsClass.getLoaded();
|
||||||
|
for (let object of loadedObjects) {
|
||||||
|
if (ids.includes(object.id)) {
|
||||||
|
await object.reload(null, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await Zotero.Notifier.trigger('modify', 'item', ids, {});
|
||||||
|
|
||||||
|
await OS.File.writeAtomic(path, new Uint8Array(modifiedBuf));
|
||||||
|
let mtime = Math.floor(await attachment.attachmentModificationTime / 1000);
|
||||||
|
attachment.attachmentLastProcessedModificationTime = mtime;
|
||||||
|
await attachment.saveTx({
|
||||||
|
skipAll: true
|
||||||
|
});
|
||||||
|
|
||||||
|
Zotero.debug(`Deleted pages for item ${attachment.libraryKey} in ${new Date() - t} ms`);
|
||||||
|
}, isPriority);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rotate pages in PDF attachment
|
||||||
|
*
|
||||||
|
* @param {Integer} itemID Attachment item id
|
||||||
|
* @param {Array} pageIndexes
|
||||||
|
* @param {Integer} degrees 90, 180, 270
|
||||||
|
* @param {Boolean} [isPriority]
|
||||||
|
* @param {String} [password]
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
async rotatePages(itemID, pageIndexes, degrees, isPriority, password) {
|
||||||
|
return this._enqueue(async () => {
|
||||||
|
let attachment = await Zotero.Items.getAsync(itemID);
|
||||||
|
|
||||||
|
Zotero.debug(`Rotating [${pageIndexes.join(', ')}] pages for item ${attachment.libraryKey}`);
|
||||||
|
let t = new Date();
|
||||||
|
|
||||||
|
if (!attachment.isPDFAttachment()) {
|
||||||
|
throw new Error('Item must be a PDF attachment');
|
||||||
|
}
|
||||||
|
|
||||||
|
let path = await attachment.getFilePathAsync();
|
||||||
|
let buf = await OS.File.read(path, {});
|
||||||
|
buf = new Uint8Array(buf).buffer;
|
||||||
|
|
||||||
|
try {
|
||||||
|
var { buf: modifiedBuf } = await this._query('rotatePages', {
|
||||||
|
buf, pageIndexes, degrees, password
|
||||||
|
}, [buf]);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
let error = new Error(`Worker 'rotatePages' failed: ${JSON.stringify({ error: e.message })}`);
|
||||||
|
try {
|
||||||
|
error.name = JSON.parse(e.message).name;
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
Zotero.logError(e);
|
||||||
|
}
|
||||||
|
Zotero.logError(error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
await OS.File.writeAtomic(path, new Uint8Array(modifiedBuf));
|
||||||
|
let mtime = Math.floor(await attachment.attachmentModificationTime / 1000);
|
||||||
|
attachment.attachmentLastProcessedModificationTime = mtime;
|
||||||
|
await attachment.saveTx({
|
||||||
|
skipAll: true
|
||||||
|
});
|
||||||
|
|
||||||
|
Zotero.debug(`Rotated pages for item ${attachment.libraryKey} in ${new Date() - t} ms`);
|
||||||
|
}, isPriority);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Zotero.PDFWorker = new PDFWorker();
|
Zotero.PDFWorker = new PDFWorker();
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ Zotero.Prefs = new function(){
|
||||||
if (!fromVersion) {
|
if (!fromVersion) {
|
||||||
fromVersion = 0;
|
fromVersion = 0;
|
||||||
}
|
}
|
||||||
var toVersion = 5;
|
var toVersion = 6;
|
||||||
if (fromVersion < toVersion) {
|
if (fromVersion < toVersion) {
|
||||||
for (var i = fromVersion + 1; i <= toVersion; i++) {
|
for (var i = fromVersion + 1; i <= toVersion; i++) {
|
||||||
switch (i) {
|
switch (i) {
|
||||||
|
|
@ -85,6 +85,24 @@ Zotero.Prefs = new function(){
|
||||||
case 5:
|
case 5:
|
||||||
this.clear('extensions.spellcheck.inline.max-misspellings', true);
|
this.clear('extensions.spellcheck.inline.max-misspellings', true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// If the note Quick Copy setting was set to Markdown + Rich Text but in a
|
||||||
|
// non-default way (e.g., because of whitespace differences), clear the pref
|
||||||
|
// to pick up the new app-link options
|
||||||
|
case 6:
|
||||||
|
var o = this.get('export.noteQuickCopy.setting');
|
||||||
|
try {
|
||||||
|
o = JSON.parse(o);
|
||||||
|
if (o.mode == 'export'
|
||||||
|
&& o.id == Zotero.Translators.TRANSLATOR_ID_MARKDOWN_AND_RICH_TEXT) {
|
||||||
|
this.clear('export.noteQuickCopy.setting');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
Zotero.logError(e);
|
||||||
|
this.clear('export.noteQuickCopy.setting');
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.set('prefVersion', toVersion);
|
this.set('prefVersion', toVersion);
|
||||||
|
|
@ -230,6 +248,7 @@ Zotero.Prefs = new function(){
|
||||||
Zotero.setFontSize(
|
Zotero.setFontSize(
|
||||||
Zotero.getActiveZoteroPane().document.getElementById('zotero-pane')
|
Zotero.getActiveZoteroPane().document.getElementById('zotero-pane')
|
||||||
);
|
);
|
||||||
|
Zotero.setFontSize(Zotero.getActiveZoteroPane().document.getElementById('zotero-context-pane'));
|
||||||
Zotero.getActiveZoteroPane().collectionsView && Zotero.getActiveZoteroPane().collectionsView.updateFontSize();
|
Zotero.getActiveZoteroPane().collectionsView && Zotero.getActiveZoteroPane().collectionsView.updateFontSize();
|
||||||
Zotero.getActiveZoteroPane().itemsView && Zotero.getActiveZoteroPane().itemsView.updateFontSize();
|
Zotero.getActiveZoteroPane().itemsView && Zotero.getActiveZoteroPane().itemsView.updateFontSize();
|
||||||
}],
|
}],
|
||||||
|
|
@ -358,12 +377,13 @@ Zotero.Prefs = new function(){
|
||||||
delete _observersBySymbol[symbol];
|
delete _observersBySymbol[symbol];
|
||||||
|
|
||||||
var [name, handler] = obs;
|
var [name, handler] = obs;
|
||||||
var i = obs.indexOf(handler);
|
var handlers = _observers[name];
|
||||||
|
var i = handlers.indexOf(handler);
|
||||||
if (i == -1) {
|
if (i == -1) {
|
||||||
Zotero.debug("Handler was not registered for preference " + name, 2);
|
Zotero.debug("Handler was not registered for preference " + name, 2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
obs.splice(i, 1);
|
handlers.splice(i, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -269,6 +269,9 @@ Zotero.QuickCopy = new function() {
|
||||||
// Allow to reuse items array
|
// Allow to reuse items array
|
||||||
translation.setItems(items.slice());
|
translation.setItems(items.slice());
|
||||||
translation.setTranslator(format.id);
|
translation.setTranslator(format.id);
|
||||||
|
if (format.options) {
|
||||||
|
translation.setDisplayOptions(format.options);
|
||||||
|
}
|
||||||
translation.setHandler("done", callback);
|
translation.setHandler("done", callback);
|
||||||
translation.translate();
|
translation.translate();
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -322,14 +325,19 @@ Zotero.QuickCopy = new function() {
|
||||||
var _loadNoteOutputFormat = async function () {
|
var _loadNoteOutputFormat = async function () {
|
||||||
var format = Zotero.Prefs.get("export.noteQuickCopy.setting");
|
var format = Zotero.Prefs.get("export.noteQuickCopy.setting");
|
||||||
format = Zotero.QuickCopy.unserializeSetting(format);
|
format = Zotero.QuickCopy.unserializeSetting(format);
|
||||||
// If virtual "Markdown + Rich Text" translator is selected, preload Note Markdown and
|
|
||||||
// Note HTML translators
|
// Always preload Note Markdown and Note HTML translators. They're both needed for note
|
||||||
if (format.id == Zotero.Translators.TRANSLATOR_ID_MARKDOWN_AND_RICH_TEXT) {
|
// dragging if the format is "Markdown + Rich Text", HTML is needed for note dragging if
|
||||||
await _preloadFormat({ mode: 'export', id: Zotero.Translators.TRANSLATOR_ID_NOTE_MARKDOWN });
|
// the format is "HTML", and they're both needed for copying or dragging from the note
|
||||||
await _preloadFormat({ mode: 'export', id: Zotero.Translators.TRANSLATOR_ID_NOTE_HTML });
|
// editor, which uses `noWait`.
|
||||||
return;
|
await _preloadFormat({ mode: 'export', id: Zotero.Translators.TRANSLATOR_ID_NOTE_MARKDOWN });
|
||||||
|
await _preloadFormat({ mode: 'export', id: Zotero.Translators.TRANSLATOR_ID_NOTE_HTML });
|
||||||
|
|
||||||
|
// If there's another format, preload it for note item dragging
|
||||||
|
if (format.id != Zotero.Translators.TRANSLATOR_ID_MARKDOWN_AND_RICH_TEXT
|
||||||
|
&& format.id != Zotero.Translators.TRANSLATOR_ID_NOTE_HTML) {
|
||||||
|
await _preloadFormat(format);
|
||||||
}
|
}
|
||||||
return _preloadFormat(format);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@
|
||||||
***** END LICENSE BLOCK *****
|
***** END LICENSE BLOCK *****
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import FilePicker from 'zotero/modules/filePicker';
|
||||||
|
|
||||||
class ReaderInstance {
|
class ReaderInstance {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.pdfStateFileName = '.zotero-pdf-state';
|
this.pdfStateFileName = '.zotero-pdf-state';
|
||||||
|
|
@ -50,7 +52,48 @@ class ReaderInstance {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async open({ itemID, state, location }) {
|
getSecondViewState() {
|
||||||
|
let state = this._iframeWindow.wrappedJSObject.getSecondViewState();
|
||||||
|
return state ? JSON.parse(JSON.stringify(state)) : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
async migrateMendeleyColors(libraryID, annotations) {
|
||||||
|
let colorMap = new Map();
|
||||||
|
colorMap.set('#fff5ad', '#ffd400');
|
||||||
|
colorMap.set('#ffb5b6', '#ff6666');
|
||||||
|
colorMap.set('#bae2ff', '#2ea8e5');
|
||||||
|
colorMap.set('#d3c2ff', '#a28ae5');
|
||||||
|
colorMap.set('#dcffb0', '#5fb236');
|
||||||
|
let updatedAnnotations = [];
|
||||||
|
for (let annotation of annotations) {
|
||||||
|
let color = colorMap.get(annotation.color);
|
||||||
|
if (color) {
|
||||||
|
annotation.color = color;
|
||||||
|
updatedAnnotations.push(annotation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!updatedAnnotations.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Zotero.debug('Migrating Mendeley colors');
|
||||||
|
let notifierQueue = new Zotero.Notifier.Queue();
|
||||||
|
try {
|
||||||
|
for (let annotation of updatedAnnotations) {
|
||||||
|
let { id: key, color } = annotation;
|
||||||
|
let item = Zotero.Items.getByLibraryAndKey(libraryID, key);
|
||||||
|
if (item && item.isEditable()) {
|
||||||
|
item.annotationColor = color;
|
||||||
|
await item.saveTx({ skipDateModifiedUpdate: true, notifierQueue });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
await Zotero.Notifier.commit(notifierQueue);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
async open({ itemID, state, location, secondViewState }) {
|
||||||
let { libraryID } = Zotero.Items.getLibraryAndKeyFromID(itemID);
|
let { libraryID } = Zotero.Items.getLibraryAndKeyFromID(itemID);
|
||||||
let library = Zotero.Libraries.get(libraryID);
|
let library = Zotero.Libraries.get(libraryID);
|
||||||
await library.waitForDataLoad('item');
|
await library.waitForDataLoad('item');
|
||||||
|
|
@ -64,10 +107,27 @@ class ReaderInstance {
|
||||||
// Set `ReaderTab` title as fast as possible
|
// Set `ReaderTab` title as fast as possible
|
||||||
this.updateTitle();
|
this.updateTitle();
|
||||||
let path = await item.getFilePathAsync();
|
let path = await item.getFilePathAsync();
|
||||||
|
// Check file size, otherwise we get uncatchable error:
|
||||||
|
// JavaScript error: resource://gre/modules/osfile/osfile_native.jsm, line 60: RangeError: invalid array length
|
||||||
|
// See more https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Invalid_array_length
|
||||||
|
let fileSize = (await OS.File.stat(path)).size;
|
||||||
|
// Max ArrayBuffer size before fx89 is 2GB-1 bytes
|
||||||
|
if (fileSize > Math.pow(2, 31) - 1) {
|
||||||
|
throw new Error(`The file "${path}" is too large`);
|
||||||
|
}
|
||||||
let buf = await OS.File.read(path, {});
|
let buf = await OS.File.read(path, {});
|
||||||
buf = new Uint8Array(buf).buffer;
|
buf = new Uint8Array(buf).buffer;
|
||||||
let annotationItems = item.getAnnotations();
|
let annotationItems = item.getAnnotations();
|
||||||
let annotations = (await Promise.all(annotationItems.map(x => this._getAnnotation(x)))).filter(x => x);
|
let annotations = (await Promise.all(annotationItems.map(x => this._getAnnotation(x)))).filter(x => x);
|
||||||
|
|
||||||
|
// TODO: Remove after some time
|
||||||
|
// Migrate Mendeley colors to Zotero PDF reader colors
|
||||||
|
let migrated = await this.migrateMendeleyColors(libraryID, annotations);
|
||||||
|
if (migrated) {
|
||||||
|
annotationItems = item.getAnnotations();
|
||||||
|
annotations = (await Promise.all(annotationItems.map(x => this._getAnnotation(x)))).filter(x => x);
|
||||||
|
}
|
||||||
|
|
||||||
this.annotationItemIDs = annotationItems.map(x => x.id);
|
this.annotationItemIDs = annotationItems.map(x => x.id);
|
||||||
state = state || await this._getState();
|
state = state || await this._getState();
|
||||||
this._postMessage({
|
this._postMessage({
|
||||||
|
|
@ -75,6 +135,7 @@ class ReaderInstance {
|
||||||
buf,
|
buf,
|
||||||
annotations,
|
annotations,
|
||||||
state,
|
state,
|
||||||
|
secondViewState,
|
||||||
location,
|
location,
|
||||||
readOnly: this._isReadOnly(),
|
readOnly: this._isReadOnly(),
|
||||||
authorName: item.library.libraryType === 'group' ? Zotero.Users.getCurrentName() : '',
|
authorName: item.library.libraryType === 'group' ? Zotero.Users.getCurrentName() : '',
|
||||||
|
|
@ -83,6 +144,7 @@ class ReaderInstance {
|
||||||
sidebarOpen: this._sidebarOpen,
|
sidebarOpen: this._sidebarOpen,
|
||||||
bottomPlaceholderHeight: this._bottomPlaceholderHeight,
|
bottomPlaceholderHeight: this._bottomPlaceholderHeight,
|
||||||
rtl: Zotero.rtl,
|
rtl: Zotero.rtl,
|
||||||
|
fontSize: Zotero.Prefs.get('fontSize'),
|
||||||
localizedStrings: {
|
localizedStrings: {
|
||||||
...Zotero.Intl.getPrefixedStrings('general.'),
|
...Zotero.Intl.getPrefixedStrings('general.'),
|
||||||
...Zotero.Intl.getPrefixedStrings('pdfReader.')
|
...Zotero.Intl.getPrefixedStrings('pdfReader.')
|
||||||
|
|
@ -90,9 +152,20 @@ class ReaderInstance {
|
||||||
}, [buf]);
|
}, [buf]);
|
||||||
// Set title once again, because `ReaderWindow` isn't loaded the first time
|
// Set title once again, because `ReaderWindow` isn't loaded the first time
|
||||||
this.updateTitle();
|
this.updateTitle();
|
||||||
|
|
||||||
|
this._prefObserverIDs = [
|
||||||
|
Zotero.Prefs.registerObserver('fontSize', this._handleFontSizeChange)
|
||||||
|
];
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uninit() {
|
||||||
|
if (this._prefObserverIDs) {
|
||||||
|
this._prefObserverIDs.forEach(id => Zotero.Prefs.unregisterObserver(id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
get itemID() {
|
get itemID() {
|
||||||
return this._itemID;
|
return this._itemID;
|
||||||
}
|
}
|
||||||
|
|
@ -202,6 +275,14 @@ class ReaderInstance {
|
||||||
return this._iframeWindow.eval('PDFViewerApplication.pdfViewer.currentScaleValue === "page-fit"');
|
return this._iframeWindow.eval('PDFViewerApplication.pdfViewer.currentScaleValue === "page-fit"');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isSplitVerticallyActive() {
|
||||||
|
return this._iframeWindow.wrappedJSObject.getSplitType() === 'vertical';
|
||||||
|
}
|
||||||
|
|
||||||
|
isSplitHorizontallyActive() {
|
||||||
|
return this._iframeWindow.wrappedJSObject.getSplitType() === 'horizontal';
|
||||||
|
}
|
||||||
|
|
||||||
allowNavigateFirstPage() {
|
allowNavigateFirstPage() {
|
||||||
return this._iframeWindow.eval('PDFViewerApplication.pdfViewer.currentPageNumber > 1');
|
return this._iframeWindow.eval('PDFViewerApplication.pdfViewer.currentPageNumber > 1');
|
||||||
}
|
}
|
||||||
|
|
@ -250,6 +331,33 @@ class ReaderInstance {
|
||||||
return !index;
|
return !index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
promptToDeletePages(num) {
|
||||||
|
let ps = Services.prompt;
|
||||||
|
let buttonFlags = ps.BUTTON_POS_0 * ps.BUTTON_TITLE_IS_STRING
|
||||||
|
+ ps.BUTTON_POS_1 * ps.BUTTON_TITLE_CANCEL;
|
||||||
|
let index = ps.confirmEx(
|
||||||
|
null,
|
||||||
|
Zotero.getString('pdfReader.promptDeletePages.title'),
|
||||||
|
Zotero.getString(
|
||||||
|
'pdfReader.promptDeletePages.text',
|
||||||
|
new Intl.NumberFormat().format(num),
|
||||||
|
num
|
||||||
|
),
|
||||||
|
buttonFlags,
|
||||||
|
Zotero.getString('general.continue'),
|
||||||
|
null, null, null, {}
|
||||||
|
);
|
||||||
|
return !index;
|
||||||
|
}
|
||||||
|
|
||||||
|
async reload(data) {
|
||||||
|
let item = Zotero.Items.get(this._itemID);
|
||||||
|
let path = await item.getFilePathAsync();
|
||||||
|
let buf = await OS.File.read(path, {});
|
||||||
|
buf = new Uint8Array(buf).buffer;
|
||||||
|
this._postMessage({ action: 'reload', buf, data }, [buf]);
|
||||||
|
}
|
||||||
|
|
||||||
async menuCmd(cmd) {
|
async menuCmd(cmd) {
|
||||||
if (cmd === 'transferFromPDF') {
|
if (cmd === 'transferFromPDF') {
|
||||||
if (this.promptToTransferAnnotations(true)) {
|
if (this.promptToTransferAnnotations(true)) {
|
||||||
|
|
@ -281,6 +389,24 @@ class ReaderInstance {
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if (cmd === 'rotateLeft') {
|
||||||
|
await this._rotateCurrentPage(270);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (cmd === 'rotateRight') {
|
||||||
|
await this._rotateCurrentPage(90);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (cmd === 'rotate180') {
|
||||||
|
await this._rotateCurrentPage(180);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (cmd === 'splitVertically') {
|
||||||
|
this._splitVertically();
|
||||||
|
}
|
||||||
|
else if (cmd === 'splitHorizontally') {
|
||||||
|
this._splitHorizontally();
|
||||||
|
}
|
||||||
|
|
||||||
let data = {
|
let data = {
|
||||||
action: 'menuCmd',
|
action: 'menuCmd',
|
||||||
|
|
@ -317,8 +443,8 @@ class ReaderInstance {
|
||||||
// If exporting with virtual "Markdown + Rich Text" translator, call Note Markdown
|
// If exporting with virtual "Markdown + Rich Text" translator, call Note Markdown
|
||||||
// and Note HTML translators instead
|
// and Note HTML translators instead
|
||||||
if (format.id === Zotero.Translators.TRANSLATOR_ID_MARKDOWN_AND_RICH_TEXT) {
|
if (format.id === Zotero.Translators.TRANSLATOR_ID_MARKDOWN_AND_RICH_TEXT) {
|
||||||
let markdownFormat = { mode: 'export', id: Zotero.Translators.TRANSLATOR_ID_NOTE_MARKDOWN };
|
let markdownFormat = { mode: 'export', id: Zotero.Translators.TRANSLATOR_ID_NOTE_MARKDOWN, options: format.markdownOptions };
|
||||||
let htmlFormat = { mode: 'export', id: Zotero.Translators.TRANSLATOR_ID_NOTE_HTML };
|
let htmlFormat = { mode: 'export', id: Zotero.Translators.TRANSLATOR_ID_NOTE_HTML, options: format.htmlOptions };
|
||||||
Zotero.QuickCopy.getContentFromItems(items, markdownFormat, (obj, worked) => {
|
Zotero.QuickCopy.getContentFromItems(items, markdownFormat, (obj, worked) => {
|
||||||
if (!worked) {
|
if (!worked) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -369,6 +495,54 @@ class ReaderInstance {
|
||||||
);
|
);
|
||||||
return !index;
|
return !index;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this._iframeWindow.wrappedJSObject.zoteroCopyImage = async (dataURL) => {
|
||||||
|
let parts = dataURL.split(',');
|
||||||
|
if (!parts[0].includes('base64')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let bstr = atob(parts[1]);
|
||||||
|
let n = bstr.length;
|
||||||
|
let u8arr = new Uint8Array(n);
|
||||||
|
while (n--) {
|
||||||
|
u8arr[n] = bstr.charCodeAt(n);
|
||||||
|
}
|
||||||
|
let imgTools = Components.classes["@mozilla.org/image/tools;1"]
|
||||||
|
.getService(Components.interfaces.imgITools);
|
||||||
|
let transferable = Components.classes['@mozilla.org/widget/transferable;1']
|
||||||
|
.createInstance(Components.interfaces.nsITransferable);
|
||||||
|
let clipboardService = Components.classes['@mozilla.org/widget/clipboard;1']
|
||||||
|
.getService(Components.interfaces.nsIClipboard);
|
||||||
|
let imgPtr = Components.classes["@mozilla.org/supports-interface-pointer;1"]
|
||||||
|
.createInstance(Components.interfaces.nsISupportsInterfacePointer);
|
||||||
|
let mimeType = `image/png`;
|
||||||
|
imgPtr.data = imgTools.decodeImageFromArrayBuffer(u8arr.buffer, mimeType);
|
||||||
|
transferable.init(null);
|
||||||
|
transferable.addDataFlavor(mimeType);
|
||||||
|
transferable.setTransferData(mimeType, imgPtr, 0);
|
||||||
|
clipboardService.setData(transferable, null, Components.interfaces.nsIClipboard.kGlobalClipboard);
|
||||||
|
};
|
||||||
|
|
||||||
|
this._iframeWindow.wrappedJSObject.zoteroSaveImageAs = async (dataURL) => {
|
||||||
|
let fp = new FilePicker();
|
||||||
|
fp.init(this._iframeWindow, Zotero.getString('pdfReader.saveImageAs'), fp.modeSave);
|
||||||
|
fp.appendFilter("PNG", "*.png");
|
||||||
|
fp.defaultString = Zotero.getString('fileTypes.image').toLowerCase() + '.png';
|
||||||
|
let rv = await fp.show();
|
||||||
|
if (rv === fp.returnOK || rv === fp.returnReplace) {
|
||||||
|
let outputPath = fp.file;
|
||||||
|
let parts = dataURL.split(',');
|
||||||
|
if (parts[0].includes('base64')) {
|
||||||
|
let bstr = atob(parts[1]);
|
||||||
|
let n = bstr.length;
|
||||||
|
let u8arr = new Uint8Array(n);
|
||||||
|
while (n--) {
|
||||||
|
u8arr[n] = bstr.charCodeAt(n);
|
||||||
|
}
|
||||||
|
await OS.File.writeAtomic(outputPath, u8arr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async _setState(state) {
|
async _setState(state) {
|
||||||
|
|
@ -424,6 +598,10 @@ class ReaderInstance {
|
||||||
|| item.parentItem && item.parentItem.deleted;
|
|| item.parentItem && item.parentItem.deleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_handleFontSizeChange = () => {
|
||||||
|
this._postMessage({ action: 'setFontSize', fontSize: Zotero.Prefs.get('fontSize') });
|
||||||
|
};
|
||||||
|
|
||||||
_dataURLtoBlob(dataurl) {
|
_dataURLtoBlob(dataurl) {
|
||||||
let parts = dataurl.split(',');
|
let parts = dataurl.split(',');
|
||||||
let mime = parts[0].match(/:(.*?);/)[1];
|
let mime = parts[0].match(/:(.*?);/)[1];
|
||||||
|
|
@ -444,6 +622,33 @@ class ReaderInstance {
|
||||||
return `data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><rect shape-rendering="geometricPrecision" fill="${fill}" stroke-width="2" x="2" y="2" stroke="${stroke}" width="12" height="12" rx="3"/></svg>`;
|
return `data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><rect shape-rendering="geometricPrecision" fill="${fill}" stroke-width="2" x="2" y="2" stroke="${stroke}" width="12" height="12" rx="3"/></svg>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _rotateCurrentPage(degrees) {
|
||||||
|
let pageIndex = this._iframeWindow.wrappedJSObject.PDFViewerApplication.pdfViewer.currentPageNumber - 1;
|
||||||
|
this._postMessage({ action: 'reloading' });
|
||||||
|
await Zotero.PDFWorker.rotatePages(this._itemID, [pageIndex], degrees, true);
|
||||||
|
await this.reload({ rotatedPageIndexes: [pageIndex] });
|
||||||
|
}
|
||||||
|
|
||||||
|
_splitVertically() {
|
||||||
|
if (this.isSplitVerticallyActive()) {
|
||||||
|
this._iframeWindow.wrappedJSObject.unsplitView();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this._iframeWindow.wrappedJSObject.splitView();
|
||||||
|
}
|
||||||
|
setTimeout(() => this._updateSecondViewState(), 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
_splitHorizontally() {
|
||||||
|
if (this.isSplitHorizontallyActive()) {
|
||||||
|
this._iframeWindow.wrappedJSObject.unsplitView();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this._iframeWindow.wrappedJSObject.splitView(true);
|
||||||
|
}
|
||||||
|
setTimeout(() => this._updateSecondViewState(), 500);
|
||||||
|
}
|
||||||
|
|
||||||
_openTagsPopup(item, selector) {
|
_openTagsPopup(item, selector) {
|
||||||
let menupopup = this._window.document.createElement('menupopup');
|
let menupopup = this._window.document.createElement('menupopup');
|
||||||
menupopup.className = 'tags-popup';
|
menupopup.className = 'tags-popup';
|
||||||
|
|
@ -462,7 +667,7 @@ class ReaderInstance {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_openPagePopup(data) {
|
_openPagePopup(data, secondView) {
|
||||||
let popup = this._window.document.createElement('menupopup');
|
let popup = this._window.document.createElement('menupopup');
|
||||||
this._popupset.appendChild(popup);
|
this._popupset.appendChild(popup);
|
||||||
popup.addEventListener('popuphidden', function () {
|
popup.addEventListener('popuphidden', function () {
|
||||||
|
|
@ -483,14 +688,14 @@ class ReaderInstance {
|
||||||
menuitem = this._window.document.createElement('menuitem');
|
menuitem = this._window.document.createElement('menuitem');
|
||||||
menuitem.setAttribute('label', Zotero.getString('pdfReader.zoomIn'));
|
menuitem.setAttribute('label', Zotero.getString('pdfReader.zoomIn'));
|
||||||
menuitem.addEventListener('command', () => {
|
menuitem.addEventListener('command', () => {
|
||||||
this._postMessage({ action: 'popupCmd', cmd: 'zoomIn' });
|
this._postMessage({ action: 'popupCmd', cmd: 'zoomIn' }, [], secondView);
|
||||||
});
|
});
|
||||||
popup.appendChild(menuitem);
|
popup.appendChild(menuitem);
|
||||||
// Zoom out
|
// Zoom out
|
||||||
menuitem = this._window.document.createElement('menuitem');
|
menuitem = this._window.document.createElement('menuitem');
|
||||||
menuitem.setAttribute('label', Zotero.getString('pdfReader.zoomOut'));
|
menuitem.setAttribute('label', Zotero.getString('pdfReader.zoomOut'));
|
||||||
menuitem.addEventListener('command', () => {
|
menuitem.addEventListener('command', () => {
|
||||||
this._postMessage({ action: 'popupCmd', cmd: 'zoomOut' });
|
this._postMessage({ action: 'popupCmd', cmd: 'zoomOut' }, [], secondView);
|
||||||
});
|
});
|
||||||
popup.appendChild(menuitem);
|
popup.appendChild(menuitem);
|
||||||
// Zoom 'Auto'
|
// Zoom 'Auto'
|
||||||
|
|
@ -499,7 +704,7 @@ class ReaderInstance {
|
||||||
menuitem.setAttribute('type', 'checkbox');
|
menuitem.setAttribute('type', 'checkbox');
|
||||||
menuitem.setAttribute('checked', data.isZoomAuto);
|
menuitem.setAttribute('checked', data.isZoomAuto);
|
||||||
menuitem.addEventListener('command', () => {
|
menuitem.addEventListener('command', () => {
|
||||||
this._postMessage({ action: 'popupCmd', cmd: 'zoomAuto' });
|
this._postMessage({ action: 'popupCmd', cmd: 'zoomAuto' }, [], secondView);
|
||||||
});
|
});
|
||||||
popup.appendChild(menuitem);
|
popup.appendChild(menuitem);
|
||||||
// Zoom 'Page Width'
|
// Zoom 'Page Width'
|
||||||
|
|
@ -508,7 +713,7 @@ class ReaderInstance {
|
||||||
menuitem.setAttribute('type', 'checkbox');
|
menuitem.setAttribute('type', 'checkbox');
|
||||||
menuitem.setAttribute('checked', data.isZoomPageWidth);
|
menuitem.setAttribute('checked', data.isZoomPageWidth);
|
||||||
menuitem.addEventListener('command', () => {
|
menuitem.addEventListener('command', () => {
|
||||||
this._postMessage({ action: 'popupCmd', cmd: 'zoomPageWidth' });
|
this._postMessage({ action: 'popupCmd', cmd: 'zoomPageWidth' }, [], secondView);
|
||||||
});
|
});
|
||||||
popup.appendChild(menuitem);
|
popup.appendChild(menuitem);
|
||||||
// Zoom 'Page Height'
|
// Zoom 'Page Height'
|
||||||
|
|
@ -517,17 +722,33 @@ class ReaderInstance {
|
||||||
menuitem.setAttribute('type', 'checkbox');
|
menuitem.setAttribute('type', 'checkbox');
|
||||||
menuitem.setAttribute('checked', data.isZoomPageHeight);
|
menuitem.setAttribute('checked', data.isZoomPageHeight);
|
||||||
menuitem.addEventListener('command', () => {
|
menuitem.addEventListener('command', () => {
|
||||||
this._postMessage({ action: 'popupCmd', cmd: 'zoomPageHeight' });
|
this._postMessage({ action: 'popupCmd', cmd: 'zoomPageHeight' }, [], secondView);
|
||||||
});
|
});
|
||||||
popup.appendChild(menuitem);
|
popup.appendChild(menuitem);
|
||||||
// Separator
|
// Separator
|
||||||
popup.appendChild(this._window.document.createElement('menuseparator'));
|
popup.appendChild(this._window.document.createElement('menuseparator'));
|
||||||
|
// Split Horizontally
|
||||||
|
menuitem = this._window.document.createElement('menuitem');
|
||||||
|
menuitem.setAttribute('label', Zotero.getString('pdfReader.splitHorizontally'));
|
||||||
|
menuitem.setAttribute('type', 'checkbox');
|
||||||
|
menuitem.setAttribute('checked', this.isSplitHorizontallyActive());
|
||||||
|
menuitem.addEventListener('command', () => this._splitHorizontally());
|
||||||
|
popup.appendChild(menuitem);
|
||||||
|
// Split Vertically
|
||||||
|
menuitem = this._window.document.createElement('menuitem');
|
||||||
|
menuitem.setAttribute('label', Zotero.getString('pdfReader.splitVertically'));
|
||||||
|
menuitem.setAttribute('type', 'checkbox');
|
||||||
|
menuitem.setAttribute('checked', this.isSplitVerticallyActive());
|
||||||
|
menuitem.addEventListener('command', () => this._splitVertically());
|
||||||
|
popup.appendChild(menuitem);
|
||||||
|
// Separator
|
||||||
|
popup.appendChild(this._window.document.createElement('menuseparator'));
|
||||||
// Next page
|
// Next page
|
||||||
menuitem = this._window.document.createElement('menuitem');
|
menuitem = this._window.document.createElement('menuitem');
|
||||||
menuitem.setAttribute('label', Zotero.getString('pdfReader.nextPage'));
|
menuitem.setAttribute('label', Zotero.getString('pdfReader.nextPage'));
|
||||||
menuitem.setAttribute('disabled', !data.enableNextPage);
|
menuitem.setAttribute('disabled', !data.enableNextPage);
|
||||||
menuitem.addEventListener('command', () => {
|
menuitem.addEventListener('command', () => {
|
||||||
this._postMessage({ action: 'popupCmd', cmd: 'nextPage' });
|
this._postMessage({ action: 'popupCmd', cmd: 'nextPage' }, [], secondView);
|
||||||
});
|
});
|
||||||
popup.appendChild(menuitem);
|
popup.appendChild(menuitem);
|
||||||
// Previous page
|
// Previous page
|
||||||
|
|
@ -535,7 +756,7 @@ class ReaderInstance {
|
||||||
menuitem.setAttribute('label', Zotero.getString('pdfReader.previousPage'));
|
menuitem.setAttribute('label', Zotero.getString('pdfReader.previousPage'));
|
||||||
menuitem.setAttribute('disabled', !data.enablePrevPage);
|
menuitem.setAttribute('disabled', !data.enablePrevPage);
|
||||||
menuitem.addEventListener('command', () => {
|
menuitem.addEventListener('command', () => {
|
||||||
this._postMessage({ action: 'popupCmd', cmd: 'prevPage' });
|
this._postMessage({ action: 'popupCmd', cmd: 'prevPage' }, [], secondView);
|
||||||
});
|
});
|
||||||
popup.appendChild(menuitem);
|
popup.appendChild(menuitem);
|
||||||
popup.openPopupAtScreen(data.x, data.y, true);
|
popup.openPopupAtScreen(data.x, data.y, true);
|
||||||
|
|
@ -614,6 +835,26 @@ class ReaderInstance {
|
||||||
}
|
}
|
||||||
// Separator
|
// Separator
|
||||||
popup.appendChild(this._window.document.createElement('menuseparator'));
|
popup.appendChild(this._window.document.createElement('menuseparator'));
|
||||||
|
|
||||||
|
if (data.enableImageOptions) {
|
||||||
|
// Copy Image
|
||||||
|
menuitem = this._window.document.createElement('menuitem');
|
||||||
|
menuitem.setAttribute('label', Zotero.getString('pdfReader.copyImage'));
|
||||||
|
menuitem.addEventListener('command', () => {
|
||||||
|
this._postMessage({ action: 'popupCmd', cmd: 'copyImage', data });
|
||||||
|
});
|
||||||
|
popup.appendChild(menuitem);
|
||||||
|
// Save Image As…
|
||||||
|
menuitem = this._window.document.createElement('menuitem');
|
||||||
|
menuitem.setAttribute('label', Zotero.getString('pdfReader.saveImageAs'));
|
||||||
|
menuitem.addEventListener('command', () => {
|
||||||
|
this._postMessage({ action: 'popupCmd', cmd: 'saveImageAs', data });
|
||||||
|
});
|
||||||
|
popup.appendChild(menuitem);
|
||||||
|
// Separator
|
||||||
|
popup.appendChild(this._window.document.createElement('menuseparator'));
|
||||||
|
}
|
||||||
|
|
||||||
// Delete
|
// Delete
|
||||||
menuitem = this._window.document.createElement('menuitem');
|
menuitem = this._window.document.createElement('menuitem');
|
||||||
menuitem.setAttribute('label', Zotero.getString('general.delete'));
|
menuitem.setAttribute('label', Zotero.getString('general.delete'));
|
||||||
|
|
@ -661,6 +902,64 @@ class ReaderInstance {
|
||||||
popup.openPopup(element, 'after_start', 0, 0, true);
|
popup.openPopup(element, 'after_start', 0, 0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_openThumbnailPopup(data) {
|
||||||
|
let popup = this._window.document.createElement('menupopup');
|
||||||
|
this._popupset.appendChild(popup);
|
||||||
|
popup.addEventListener('popuphidden', function () {
|
||||||
|
popup.remove();
|
||||||
|
});
|
||||||
|
let menuitem;
|
||||||
|
// Rotate Left
|
||||||
|
menuitem = this._window.document.createElement('menuitem');
|
||||||
|
menuitem.setAttribute('label', Zotero.getString('pdfReader.rotateLeft'));
|
||||||
|
menuitem.setAttribute('disabled', this._isReadOnly());
|
||||||
|
menuitem.addEventListener('command', async () => {
|
||||||
|
this._postMessage({ action: 'reloading' });
|
||||||
|
await Zotero.PDFWorker.rotatePages(this._itemID, data.pageIndexes, 270, true);
|
||||||
|
await this.reload({ rotatedPageIndexes: data.pageIndexes });
|
||||||
|
});
|
||||||
|
popup.appendChild(menuitem);
|
||||||
|
// Rotate Right
|
||||||
|
menuitem = this._window.document.createElement('menuitem');
|
||||||
|
menuitem.setAttribute('label', Zotero.getString('pdfReader.rotateRight'));
|
||||||
|
menuitem.setAttribute('disabled', this._isReadOnly());
|
||||||
|
menuitem.addEventListener('command', async () => {
|
||||||
|
this._postMessage({ action: 'reloading' });
|
||||||
|
await Zotero.PDFWorker.rotatePages(this._itemID, data.pageIndexes, 90, true);
|
||||||
|
await this.reload({ rotatedPageIndexes: data.pageIndexes });
|
||||||
|
});
|
||||||
|
popup.appendChild(menuitem);
|
||||||
|
// Rotate 180
|
||||||
|
menuitem = this._window.document.createElement('menuitem');
|
||||||
|
menuitem.setAttribute('label', Zotero.getString('pdfReader.rotate180'));
|
||||||
|
menuitem.setAttribute('disabled', this._isReadOnly());
|
||||||
|
menuitem.addEventListener('command', async () => {
|
||||||
|
this._postMessage({ action: 'reloading' });
|
||||||
|
await Zotero.PDFWorker.rotatePages(this._itemID, data.pageIndexes, 180, true);
|
||||||
|
await this.reload({ rotatedPageIndexes: data.pageIndexes });
|
||||||
|
});
|
||||||
|
popup.appendChild(menuitem);
|
||||||
|
// Separator
|
||||||
|
popup.appendChild(this._window.document.createElement('menuseparator'));
|
||||||
|
// Delete
|
||||||
|
menuitem = this._window.document.createElement('menuitem');
|
||||||
|
menuitem.setAttribute('label', Zotero.getString('general.delete'));
|
||||||
|
menuitem.setAttribute('disabled', this._isReadOnly());
|
||||||
|
menuitem.addEventListener('command', async () => {
|
||||||
|
if (this.promptToDeletePages(data.pageIndexes.length)) {
|
||||||
|
this._postMessage({ action: 'reloading' });
|
||||||
|
try {
|
||||||
|
await Zotero.PDFWorker.deletePages(this._itemID, data.pageIndexes, true);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
}
|
||||||
|
await this.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
popup.appendChild(menuitem);
|
||||||
|
popup.openPopupAtScreen(data.x, data.y, true);
|
||||||
|
}
|
||||||
|
|
||||||
_openSelectorPopup(data) {
|
_openSelectorPopup(data) {
|
||||||
let popup = this._window.document.createElement('menupopup');
|
let popup = this._window.document.createElement('menupopup');
|
||||||
this._popupset.appendChild(popup);
|
this._popupset.appendChild(popup);
|
||||||
|
|
@ -683,25 +982,52 @@ class ReaderInstance {
|
||||||
popup.openPopupAtScreen(data.x, data.y, true);
|
popup.openPopupAtScreen(data.x, data.y, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
async _postMessage(message, transfer) {
|
async _postMessage(message, transfer, secondView) {
|
||||||
await this._waitForReader();
|
await this._waitForReader();
|
||||||
this._iframeWindow.postMessage({ itemID: this._itemID, message }, this._iframeWindow.origin, transfer);
|
this._iframeWindow.postMessage({ itemID: this._itemID, message, secondView }, this._iframeWindow.origin, transfer);
|
||||||
|
}
|
||||||
|
|
||||||
|
_updateSecondViewState() {
|
||||||
|
if (this.tabID) {
|
||||||
|
let win = Zotero.getMainWindow();
|
||||||
|
if (win) {
|
||||||
|
win.Zotero_Tabs.setSecondViewState(this.tabID, this.getSecondViewState());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_handleMessage = async (event) => {
|
_handleMessage = async (event) => {
|
||||||
let message;
|
let message;
|
||||||
|
let secondViewIframeWindow = this._iframeWindow.document.getElementById('secondViewIframe');
|
||||||
|
if (secondViewIframeWindow) {
|
||||||
|
secondViewIframeWindow = secondViewIframeWindow.contentWindow;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
if (event.source !== this._iframeWindow) {
|
if (event.source !== this._iframeWindow
|
||||||
|
&& event.source !== secondViewIframeWindow) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Clone data to avoid the dead object error when the window is closed
|
// Clone data to avoid the dead object error when the window is closed
|
||||||
let data = JSON.parse(JSON.stringify(event.data));
|
let data = JSON.parse(JSON.stringify(event.data));
|
||||||
|
let { secondView } = data;
|
||||||
// Filter messages coming from previous reader instances,
|
// Filter messages coming from previous reader instances,
|
||||||
// except for `setAnnotation` to still allow saving it
|
// except for `setAnnotation` to still allow saving it
|
||||||
if (data.itemID !== this._itemID && data.message.action !== 'setAnnotation') {
|
if (data.itemID !== this._itemID && data.message.action !== 'setAnnotation') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
message = data.message;
|
message = data.message;
|
||||||
|
|
||||||
|
if (secondView) {
|
||||||
|
switch (message.action) {
|
||||||
|
case 'openPagePopup': break;
|
||||||
|
case 'setState': {
|
||||||
|
this._updateSecondViewState();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
default: return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (message.action) {
|
switch (message.action) {
|
||||||
case 'initialized': {
|
case 'initialized': {
|
||||||
this._resolveInitPromise();
|
this._resolveInitPromise();
|
||||||
|
|
@ -725,25 +1051,22 @@ class ReaderInstance {
|
||||||
saveOptions.notifierData.autoSyncDelay = Zotero.Notes.AUTO_SYNC_DELAY;
|
saveOptions.notifierData.autoSyncDelay = Zotero.Notes.AUTO_SYNC_DELAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: annotation.image is always saved separately from the rest
|
|
||||||
// of annotation properties
|
|
||||||
|
|
||||||
let item = Zotero.Items.getByLibraryAndKey(attachment.libraryID, annotation.key);
|
let item = Zotero.Items.getByLibraryAndKey(attachment.libraryID, annotation.key);
|
||||||
// Save image for read-only annotation.
|
// If annotation isn't editable, only save image to cache.
|
||||||
if (item
|
// This is the only case when saving can be triggered for non-editable annotation
|
||||||
&& !item.isEditable()
|
if (annotation.image && item && !item.isEditable()) {
|
||||||
&& annotation.image
|
|
||||||
&& !await Zotero.Annotations.hasCacheImage(item)
|
|
||||||
) {
|
|
||||||
let blob = this._dataURLtoBlob(annotation.image);
|
let blob = this._dataURLtoBlob(annotation.image);
|
||||||
await Zotero.Annotations.saveCacheImage(item, blob);
|
await Zotero.Annotations.saveCacheImage(item, blob);
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
// Save annotation, and save image to cache
|
||||||
let savedAnnotation = await Zotero.Annotations.saveFromJSON(attachment, annotation, saveOptions);
|
else {
|
||||||
if (annotation.image && !await Zotero.Annotations.hasCacheImage(savedAnnotation)) {
|
// Delete authorName to prevent setting annotationAuthorName unnecessarily
|
||||||
let blob = this._dataURLtoBlob(annotation.image);
|
delete annotation.authorName;
|
||||||
await Zotero.Annotations.saveCacheImage(savedAnnotation, blob);
|
let savedAnnotation = await Zotero.Annotations.saveFromJSON(attachment, annotation, saveOptions);
|
||||||
|
if (annotation.image) {
|
||||||
|
let blob = this._dataURLtoBlob(annotation.image);
|
||||||
|
await Zotero.Annotations.saveCacheImage(savedAnnotation, blob);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -788,7 +1111,7 @@ class ReaderInstance {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case 'openPagePopup': {
|
case 'openPagePopup': {
|
||||||
this._openPagePopup(message.data);
|
this._openPagePopup(message.data, secondView);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case 'openAnnotationPopup': {
|
case 'openAnnotationPopup': {
|
||||||
|
|
@ -799,6 +1122,14 @@ class ReaderInstance {
|
||||||
this._openColorPopup(message.data);
|
this._openColorPopup(message.data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
case 'openThumbnailPopup': {
|
||||||
|
this._openThumbnailPopup(message.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case 'openSelectorPopup': {
|
||||||
|
this._openSelectorPopup(message.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
case 'closePopup': {
|
case 'closePopup': {
|
||||||
// Note: This currently only closes tags popup when annotations are
|
// Note: This currently only closes tags popup when annotations are
|
||||||
// disappearing from pdf-reader sidebar
|
// disappearing from pdf-reader sidebar
|
||||||
|
|
@ -847,18 +1178,17 @@ class ReaderInstance {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case 'focusSplitButton': {
|
case 'focusSplitButton': {
|
||||||
let win = Zotero.getMainWindow();
|
if (this instanceof ReaderTab) {
|
||||||
if (win) {
|
let win = Zotero.getMainWindow();
|
||||||
win.document.getElementById('zotero-tb-toggle-item-pane').focus();
|
if (win) {
|
||||||
|
win.document.getElementById('zotero-tb-toggle-item-pane').focus();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case 'focusContextPane': {
|
case 'focusContextPane': {
|
||||||
let win = Zotero.getMainWindow();
|
if (this instanceof ReaderWindow || !this._window.ZoteroContextPane.focus()) {
|
||||||
if (win) {
|
this.focusFirst();
|
||||||
if (!this._window.ZoteroContextPane.focus()) {
|
|
||||||
this.focusFirst();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -925,7 +1255,7 @@ class ReaderInstance {
|
||||||
}
|
}
|
||||||
|
|
||||||
class ReaderTab extends ReaderInstance {
|
class ReaderTab extends ReaderInstance {
|
||||||
constructor({ itemID, title, sidebarWidth, sidebarOpen, bottomPlaceholderHeight, index, background }) {
|
constructor({ itemID, title, sidebarWidth, sidebarOpen, bottomPlaceholderHeight, index, tabID, background }) {
|
||||||
super();
|
super();
|
||||||
this._itemID = itemID;
|
this._itemID = itemID;
|
||||||
this._sidebarWidth = sidebarWidth;
|
this._sidebarWidth = sidebarWidth;
|
||||||
|
|
@ -934,6 +1264,7 @@ class ReaderTab extends ReaderInstance {
|
||||||
this._showItemPaneToggle = true;
|
this._showItemPaneToggle = true;
|
||||||
this._window = Services.wm.getMostRecentWindow('navigator:browser');
|
this._window = Services.wm.getMostRecentWindow('navigator:browser');
|
||||||
let { id, container } = this._window.Zotero_Tabs.add({
|
let { id, container } = this._window.Zotero_Tabs.add({
|
||||||
|
id: tabID,
|
||||||
type: 'reader',
|
type: 'reader',
|
||||||
title: title || '',
|
title: title || '',
|
||||||
index,
|
index,
|
||||||
|
|
@ -968,20 +1299,24 @@ class ReaderTab extends ReaderInstance {
|
||||||
// events in PDF reader iframe when mouse up happens over another iframe
|
// events in PDF reader iframe when mouse up happens over another iframe
|
||||||
// i.e. note-editor. There should be a better way to solve this
|
// i.e. note-editor. There should be a better way to solve this
|
||||||
this._window.addEventListener('pointerup', (event) => {
|
this._window.addEventListener('pointerup', (event) => {
|
||||||
if (this._window.Zotero_Tabs.selectedID === this.tabID
|
try {
|
||||||
&& this._iframeWindow
|
if (this._window.Zotero_Tabs.selectedID === this.tabID
|
||||||
&& event.target
|
&& this._iframeWindow
|
||||||
&& event.target.closest
|
&& event.target
|
||||||
&& !event.target.closest('#outerContainer')) {
|
&& event.target.closest
|
||||||
let evt = new this._iframeWindow.CustomEvent('mouseup', { bubbles: false });
|
&& !event.target.closest('#outerContainer')) {
|
||||||
evt.clientX = event.clientX;
|
let evt = new this._iframeWindow.CustomEvent('mouseup', { bubbles: false });
|
||||||
evt.clientY = event.clientY;
|
evt.clientX = event.clientX;
|
||||||
this._iframeWindow.dispatchEvent(evt);
|
evt.clientY = event.clientY;
|
||||||
|
this._iframeWindow.dispatchEvent(evt);
|
||||||
|
|
||||||
evt = new this._iframeWindow.CustomEvent('pointerup', { bubbles: false });
|
evt = new this._iframeWindow.CustomEvent('pointerup', { bubbles: false });
|
||||||
evt.clientX = event.clientX;
|
evt.clientX = event.clientX;
|
||||||
evt.clientY = event.clientY;
|
evt.clientY = event.clientY;
|
||||||
this._iframeWindow.dispatchEvent(evt);
|
this._iframeWindow.dispatchEvent(evt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(e) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -1080,6 +1415,8 @@ class ReaderWindow extends ReaderInstance {
|
||||||
this._window.document.getElementById('view-menuitem-zoom-auto').setAttribute('checked', this.isZoomAutoActive());
|
this._window.document.getElementById('view-menuitem-zoom-auto').setAttribute('checked', this.isZoomAutoActive());
|
||||||
this._window.document.getElementById('view-menuitem-zoom-page-width').setAttribute('checked', this.isZoomPageWidthActive());
|
this._window.document.getElementById('view-menuitem-zoom-page-width').setAttribute('checked', this.isZoomPageWidthActive());
|
||||||
this._window.document.getElementById('view-menuitem-zoom-page-height').setAttribute('checked', this.isZoomPageHeightActive());
|
this._window.document.getElementById('view-menuitem-zoom-page-height').setAttribute('checked', this.isZoomPageHeightActive());
|
||||||
|
this._window.document.getElementById('view-menuitem-split-vertically').setAttribute('checked', this.isSplitVerticallyActive());
|
||||||
|
this._window.document.getElementById('view-menuitem-split-horizontally').setAttribute('checked', this.isSplitHorizontallyActive());
|
||||||
}
|
}
|
||||||
|
|
||||||
_onGoMenuOpen() {
|
_onGoMenuOpen() {
|
||||||
|
|
@ -1139,7 +1476,7 @@ class Reader {
|
||||||
await Zotero.uiReadyPromise;
|
await Zotero.uiReadyPromise;
|
||||||
Zotero.Session.state.windows
|
Zotero.Session.state.windows
|
||||||
.filter(x => x.type == 'reader' && Zotero.Items.exists(x.itemID))
|
.filter(x => x.type == 'reader' && Zotero.Items.exists(x.itemID))
|
||||||
.forEach(x => this.open(x.itemID, null, { title: x.title, openInWindow: true }));
|
.forEach(x => this.open(x.itemID, null, { title: x.title, openInWindow: true, secondViewState: x.secondViewState }));
|
||||||
}
|
}
|
||||||
|
|
||||||
_loadSidebarState() {
|
_loadSidebarState() {
|
||||||
|
|
@ -1199,6 +1536,7 @@ class Reader {
|
||||||
for (let id of ids) {
|
for (let id of ids) {
|
||||||
let reader = Zotero.Reader.getByTabID(id);
|
let reader = Zotero.Reader.getByTabID(id);
|
||||||
if (reader) {
|
if (reader) {
|
||||||
|
reader.uninit();
|
||||||
this._readers.splice(this._readers.indexOf(reader), 1);
|
this._readers.splice(this._readers.indexOf(reader), 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1261,7 +1599,12 @@ class Reader {
|
||||||
getWindowStates() {
|
getWindowStates() {
|
||||||
return this._readers
|
return this._readers
|
||||||
.filter(r => r instanceof ReaderWindow)
|
.filter(r => r instanceof ReaderWindow)
|
||||||
.map(r => ({ type: 'reader', itemID: r._itemID, title: r._title }));
|
.map(r => ({
|
||||||
|
type: 'reader',
|
||||||
|
itemID: r._itemID,
|
||||||
|
title: r._title,
|
||||||
|
secondViewState: r.getSecondViewState()
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
async openURI(itemURI, location, options) {
|
async openURI(itemURI, location, options) {
|
||||||
|
|
@ -1270,11 +1613,24 @@ class Reader {
|
||||||
await this.open(item.id, location, options);
|
await this.open(item.id, location, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
async open(itemID, location, { title, tabIndex, openInBackground, openInWindow, allowDuplicate } = {}) {
|
async open(itemID, location, { title, tabIndex, tabID, openInBackground, openInWindow, allowDuplicate, secondViewState } = {}) {
|
||||||
this._loadSidebarState();
|
this._loadSidebarState();
|
||||||
this.triggerAnnotationsImportCheck(itemID);
|
this.triggerAnnotationsImportCheck(itemID);
|
||||||
let reader;
|
let reader;
|
||||||
|
|
||||||
|
// If duplicating is not allowed, and no reader instance is loaded for itemID,
|
||||||
|
// try to find an unloaded tab and select it. Zotero.Reader.open will then be called again
|
||||||
|
if (!allowDuplicate && !this._readers.find(r => r._itemID === itemID)) {
|
||||||
|
let win = Zotero.getMainWindow();
|
||||||
|
if (win) {
|
||||||
|
let existingTabID = win.Zotero_Tabs.getTabIDByItemID(itemID);
|
||||||
|
if (existingTabID) {
|
||||||
|
win.Zotero_Tabs.select(existingTabID, false, { location });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (openInWindow) {
|
if (openInWindow) {
|
||||||
reader = this._readers.find(r => r._itemID === itemID && (r instanceof ReaderWindow));
|
reader = this._readers.find(r => r._itemID === itemID && (r instanceof ReaderWindow));
|
||||||
}
|
}
|
||||||
|
|
@ -1298,7 +1654,7 @@ class Reader {
|
||||||
bottomPlaceholderHeight: this._bottomPlaceholderHeight
|
bottomPlaceholderHeight: this._bottomPlaceholderHeight
|
||||||
});
|
});
|
||||||
this._readers.push(reader);
|
this._readers.push(reader);
|
||||||
if (!(await reader.open({ itemID, location }))) {
|
if (!(await reader.open({ itemID, location, secondViewState }))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Zotero.Session.debounceSave();
|
Zotero.Session.debounceSave();
|
||||||
|
|
@ -1312,13 +1668,14 @@ class Reader {
|
||||||
itemID,
|
itemID,
|
||||||
title,
|
title,
|
||||||
index: tabIndex,
|
index: tabIndex,
|
||||||
|
tabID,
|
||||||
background: openInBackground,
|
background: openInBackground,
|
||||||
sidebarWidth: this._sidebarWidth,
|
sidebarWidth: this._sidebarWidth,
|
||||||
sidebarOpen: this._sidebarOpen,
|
sidebarOpen: this._sidebarOpen,
|
||||||
bottomPlaceholderHeight: this._bottomPlaceholderHeight
|
bottomPlaceholderHeight: this._bottomPlaceholderHeight
|
||||||
});
|
});
|
||||||
this._readers.push(reader);
|
this._readers.push(reader);
|
||||||
if (!(await reader.open({ itemID, location }))) {
|
if (!(await reader.open({ itemID, location, secondViewState }))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
reader.onChangeSidebarWidth = (width) => {
|
reader.onChangeSidebarWidth = (width) => {
|
||||||
|
|
@ -1340,6 +1697,7 @@ class Reader {
|
||||||
if (!openInBackground) {
|
if (!openInBackground) {
|
||||||
reader._window.focus();
|
reader._window.focus();
|
||||||
}
|
}
|
||||||
|
return reader;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
***** END LICENSE BLOCK *****
|
***** END LICENSE BLOCK *****
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Zotero.SingleFile = {
|
Zotero.SingleFile = Object.assign(Zotero.SingleFile || {}, {
|
||||||
// These are defaults from SingleFile
|
// These are defaults from SingleFile
|
||||||
// Located in: zotero/resources/SingleFile/extension/core/bg/config.js
|
// Located in: zotero/resources/SingleFile/extension/core/bg/config.js
|
||||||
CONFIG: {
|
CONFIG: {
|
||||||
|
|
@ -32,7 +32,9 @@ Zotero.SingleFile = {
|
||||||
removeUnusedFonts: true,
|
removeUnusedFonts: true,
|
||||||
removeFrames: true,
|
removeFrames: true,
|
||||||
removeImports: true,
|
removeImports: true,
|
||||||
removeScripts: true,
|
blockScripts: true,
|
||||||
|
blockVideos: true,
|
||||||
|
blockAudios: true,
|
||||||
compressHTML: true,
|
compressHTML: true,
|
||||||
compressCSS: false,
|
compressCSS: false,
|
||||||
loadDeferredImages: true,
|
loadDeferredImages: true,
|
||||||
|
|
@ -40,6 +42,7 @@ Zotero.SingleFile = {
|
||||||
loadDeferredImagesBlockCookies: false,
|
loadDeferredImagesBlockCookies: false,
|
||||||
loadDeferredImagesBlockStorage: false,
|
loadDeferredImagesBlockStorage: false,
|
||||||
loadDeferredImagesKeepZoomLevel: false,
|
loadDeferredImagesKeepZoomLevel: false,
|
||||||
|
loadDeferredImagesNativeTimeout: true, // See https://github.com/gildas-lormeau/SingleFile/issues/1026
|
||||||
filenameTemplate: "{page-title} ({date-iso} {time-locale}).html",
|
filenameTemplate: "{page-title} ({date-iso} {time-locale}).html",
|
||||||
infobarTemplate: "",
|
infobarTemplate: "",
|
||||||
includeInfobar: false,
|
includeInfobar: false,
|
||||||
|
|
@ -58,8 +61,6 @@ Zotero.SingleFile = {
|
||||||
progressBarEnabled: true,
|
progressBarEnabled: true,
|
||||||
maxResourceSizeEnabled: false,
|
maxResourceSizeEnabled: false,
|
||||||
maxResourceSize: 10,
|
maxResourceSize: 10,
|
||||||
removeAudioSrc: true,
|
|
||||||
removeVideoSrc: true,
|
|
||||||
displayInfobar: true,
|
displayInfobar: true,
|
||||||
displayStats: false,
|
displayStats: false,
|
||||||
backgroundSave: true,
|
backgroundSave: true,
|
||||||
|
|
@ -95,4 +96,4 @@ Zotero.SingleFile = {
|
||||||
insertSingleFileComment: true,
|
insertSingleFileComment: true,
|
||||||
blockMixedContent: false,
|
blockMixedContent: false,
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
|
||||||
|
|
@ -762,6 +762,8 @@ Zotero.Style.prototype.getCiteProc = function(locale, format, automaticJournalAb
|
||||||
var xml = this.getXML();
|
var xml = this.getXML();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xml = this._eventToEventTitle(xml);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var citeproc;
|
var citeproc;
|
||||||
if (Zotero.Prefs.get('cite.useCiteprocRs')) {
|
if (Zotero.Prefs.get('cite.useCiteprocRs')) {
|
||||||
|
|
@ -801,6 +803,39 @@ Zotero.Style.prototype.getCiteProc = function(locale, format, automaticJournalAb
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Temporarily substitute `event-title` for `event`
|
||||||
|
*
|
||||||
|
* Until https://github.com/citation-style-language/styles/issues/6151
|
||||||
|
*/
|
||||||
|
Zotero.Style.prototype._eventToEventTitle = function (xml) {
|
||||||
|
var parser = Components.classes["@mozilla.org/xmlextras/domparser;1"]
|
||||||
|
.createInstance(Components.interfaces.nsIDOMParser);
|
||||||
|
var doc = parser.parseFromString(xml, "text/xml");
|
||||||
|
// Ignore styles that already include `event-title`
|
||||||
|
if (doc.querySelector('[variable*="event-title"]')) {
|
||||||
|
return xml;
|
||||||
|
}
|
||||||
|
var elems = doc.querySelectorAll('[variable*="event"]');
|
||||||
|
if (!elems.length) {
|
||||||
|
return xml;
|
||||||
|
}
|
||||||
|
var changed = false;
|
||||||
|
for (let elem of elems) {
|
||||||
|
let variable = elem.getAttribute('variable');
|
||||||
|
// Must be "event" or "event foo", not, say, "event-place"
|
||||||
|
if (!/event( |$)/.test(variable)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
elem.setAttribute('variable', variable.replace(/event(?= |$)/, 'event-title'));
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
if (changed) {
|
||||||
|
xml = doc.documentElement.outerHTML;
|
||||||
|
}
|
||||||
|
return xml;
|
||||||
|
};
|
||||||
|
|
||||||
Zotero.Style.prototype.__defineGetter__("class",
|
Zotero.Style.prototype.__defineGetter__("class",
|
||||||
/**
|
/**
|
||||||
* Retrieves the style class, either from the metadata that's already loaded or by loading the file
|
* Retrieves the style class, either from the metadata that's already loaded or by loading the file
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 5595949fd1223802159fd1716a116da62fe8f917
|
Subproject commit 81991533dd3531acb9bfd6bb9457136a0af75f0f
|
||||||
|
|
@ -668,6 +668,7 @@ Zotero.Translate.ItemSaver.prototype = {
|
||||||
title: attachment.title,
|
title: attachment.title,
|
||||||
contentType: attachment.mimeType,
|
contentType: attachment.mimeType,
|
||||||
charset: attachment.charset,
|
charset: attachment.charset,
|
||||||
|
libraryID: this._libraryID,
|
||||||
parentItemID,
|
parentItemID,
|
||||||
collections: !parentItemID ? this._collections : undefined,
|
collections: !parentItemID ? this._collections : undefined,
|
||||||
saveOptions: this._saveOptions,
|
saveOptions: this._saveOptions,
|
||||||
|
|
@ -678,6 +679,7 @@ Zotero.Translate.ItemSaver.prototype = {
|
||||||
newItem = yield Zotero.Attachments.importFromFile({
|
newItem = yield Zotero.Attachments.importFromFile({
|
||||||
file: file,
|
file: file,
|
||||||
parentItemID,
|
parentItemID,
|
||||||
|
libraryID: this._libraryID,
|
||||||
collections: !parentItemID ? this._collections : undefined,
|
collections: !parentItemID ? this._collections : undefined,
|
||||||
saveOptions: this._saveOptions,
|
saveOptions: this._saveOptions,
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -263,8 +263,9 @@ Zotero.Translators = new function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
this.reinit = function (options = {}) {
|
this.reinit = async function (options = {}) {
|
||||||
return this.init(Object.assign({}, options, { reinit: true }));
|
await this.init(Object.assign({}, options, { reinit: true }));
|
||||||
|
await Zotero.QuickCopy.init();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit a0a145a4b534721148da362a3bae3befc8d65121
|
Subproject commit 4d8d7d3e92cbc3b4d62b82478e212a6f63b9a35f
|
||||||
|
|
@ -405,6 +405,12 @@ Zotero.Utilities.Internal = {
|
||||||
return s;
|
return s;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
isOnlyEmoji: function (str) {
|
||||||
|
// Remove emoji, Zero Width Joiner, and Variation Selector-16 and see if anything's left
|
||||||
|
const re = /\p{Extended_Pictographic}|\u200D|\uFE0F/gu;
|
||||||
|
return !str.replace(re, '');
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display a prompt from an error with custom buttons and a callback
|
* Display a prompt from an error with custom buttons and a callback
|
||||||
*/
|
*/
|
||||||
|
|
@ -564,11 +570,10 @@ Zotero.Utilities.Internal = {
|
||||||
|
|
||||||
const SCRIPTS = [
|
const SCRIPTS = [
|
||||||
// This first script replace in the INDEX_SCRIPTS from the single file cli loader
|
// This first script replace in the INDEX_SCRIPTS from the single file cli loader
|
||||||
"dist/single-file.js",
|
"lib/single-file.js",
|
||||||
|
|
||||||
// Web SCRIPTS
|
// Web SCRIPTS
|
||||||
"dist/web/hooks/hooks-frames-web.js",
|
"lib/single-file-hooks-frames.js",
|
||||||
"dist/web/hooks/hooks-web.js",
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const { loadSubScript } = Components.classes['@mozilla.org/moz/jssubscript-loader;1']
|
const { loadSubScript } = Components.classes['@mozilla.org/moz/jssubscript-loader;1']
|
||||||
|
|
@ -594,8 +599,8 @@ Zotero.Utilities.Internal = {
|
||||||
// List of scripts from:
|
// List of scripts from:
|
||||||
// resource/SingleFile/extension/lib/single-file/core/bg/scripts.js
|
// resource/SingleFile/extension/lib/single-file/core/bg/scripts.js
|
||||||
const frameScripts = [
|
const frameScripts = [
|
||||||
"dist/web/hooks/hooks-frames-web.js",
|
"lib/single-file-hooks-frames.js",
|
||||||
"dist/single-file-frames.js",
|
"lib/single-file-frames.js",
|
||||||
];
|
];
|
||||||
|
|
||||||
// Create sandboxes for all the frames we find
|
// Create sandboxes for all the frames we find
|
||||||
|
|
@ -647,7 +652,7 @@ Zotero.Utilities.Internal = {
|
||||||
// Mostly copied from:
|
// Mostly copied from:
|
||||||
// resources/SingleFile/extension/lib/single-file/fetch/bg/fetch.js::fetchResource
|
// resources/SingleFile/extension/lib/single-file/fetch/bg/fetch.js::fetchResource
|
||||||
sandbox.coFetch = Components.utils.exportFunction(
|
sandbox.coFetch = Components.utils.exportFunction(
|
||||||
function (url, onDone) {
|
function (url, options, onDone) {
|
||||||
const xhrRequest = new XMLHttpRequest();
|
const xhrRequest = new XMLHttpRequest();
|
||||||
xhrRequest.withCredentials = true;
|
xhrRequest.withCredentials = true;
|
||||||
xhrRequest.responseType = "arraybuffer";
|
xhrRequest.responseType = "arraybuffer";
|
||||||
|
|
@ -673,6 +678,11 @@ Zotero.Utilities.Internal = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
xhrRequest.open("GET", url, true);
|
xhrRequest.open("GET", url, true);
|
||||||
|
if (options && options.headers) {
|
||||||
|
for (const entry of Object.entries(options.headers)) {
|
||||||
|
xhrRequest.setRequestHeader(entry[0], entry[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
xhrRequest.send();
|
xhrRequest.send();
|
||||||
},
|
},
|
||||||
sandbox
|
sandbox
|
||||||
|
|
@ -683,14 +693,14 @@ Zotero.Utilities.Internal = {
|
||||||
// resources/SingleFile/extension/lib/single-file/fetch/content/content-fetch.js::fetch
|
// resources/SingleFile/extension/lib/single-file/fetch/content/content-fetch.js::fetch
|
||||||
Components.utils.evalInSandbox(
|
Components.utils.evalInSandbox(
|
||||||
`
|
`
|
||||||
ZoteroFetch = async function (url) {
|
ZoteroFetch = async function (url, options) {
|
||||||
try {
|
try {
|
||||||
let response = await fetch(url, { cache: "force-cache" });
|
let response = await fetch(url, { cache: "force-cache", headers: options.headers });
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
let response = await new Promise((resolve, reject) => {
|
let response = await new Promise((resolve, reject) => {
|
||||||
coFetch(url, (response) => {
|
coFetch(url, { headers: options.headers }, (response) => {
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
Zotero.debug("Error retrieving url: " + url);
|
Zotero.debug("Error retrieving url: " + url);
|
||||||
Zotero.debug(response);
|
Zotero.debug(response);
|
||||||
|
|
@ -1551,6 +1561,18 @@ Zotero.Utilities.Internal = {
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a localized colon to a string (which is usually just a colon, but, e.g., in French
|
||||||
|
* there's a space before it)
|
||||||
|
*
|
||||||
|
* @param {String}
|
||||||
|
* @return {String}
|
||||||
|
*/
|
||||||
|
stringWithColon: function (str) {
|
||||||
|
return Zotero.getString('punctuation.colon.withString', str);
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
resolveLocale: function (locale, locales) {
|
resolveLocale: function (locale, locales) {
|
||||||
// If the locale exists as-is, use it
|
// If the locale exists as-is, use it
|
||||||
if (locales.includes(locale)) {
|
if (locales.includes(locale)) {
|
||||||
|
|
|
||||||
|
|
@ -2098,7 +2098,7 @@ Zotero.Browser = new function() {
|
||||||
hiddenBrowser.docShell.allowJavascript = options.allowJavaScript !== false
|
hiddenBrowser.docShell.allowJavascript = options.allowJavaScript !== false
|
||||||
hiddenBrowser.docShell.allowMetaRedirects = false;
|
hiddenBrowser.docShell.allowMetaRedirects = false;
|
||||||
hiddenBrowser.docShell.allowPlugins = false;
|
hiddenBrowser.docShell.allowPlugins = false;
|
||||||
Zotero.debug("Created hidden browser (" + (nBrowsers++) + ")");
|
Zotero.debug("Created hidden browser (" + (++nBrowsers) + ")");
|
||||||
return hiddenBrowser;
|
return hiddenBrowser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,7 @@ var ZoteroPane = new function()
|
||||||
|
|
||||||
var zp = document.getElementById('zotero-pane');
|
var zp = document.getElementById('zotero-pane');
|
||||||
Zotero.setFontSize(zp);
|
Zotero.setFontSize(zp);
|
||||||
|
Zotero.setFontSize(document.getElementById('zotero-context-pane'));
|
||||||
ZoteroPane_Local.updateLayout();
|
ZoteroPane_Local.updateLayout();
|
||||||
ZoteroPane_Local.updateToolbarPosition();
|
ZoteroPane_Local.updateToolbarPosition();
|
||||||
this.updateWindow();
|
this.updateWindow();
|
||||||
|
|
@ -148,6 +149,26 @@ var ZoteroPane = new function()
|
||||||
Zotero.hiDPI = window.devicePixelRatio > 1;
|
Zotero.hiDPI = window.devicePixelRatio > 1;
|
||||||
Zotero.hiDPISuffix = Zotero.hiDPI ? "@2x" : "";
|
Zotero.hiDPISuffix = Zotero.hiDPI ? "@2x" : "";
|
||||||
|
|
||||||
|
// Show warning in toolbar for 'dev' channel builds
|
||||||
|
try {
|
||||||
|
let isDevBuild = Zotero.version.includes('-dev');
|
||||||
|
// Uncomment to test
|
||||||
|
//isDevBuild = isDevBuild || Zotero.version.includes('.SOURCE');
|
||||||
|
if (isDevBuild) {
|
||||||
|
let label = document.createElement('label');
|
||||||
|
label.setAttribute('value', 'TEST BUILD — DO NOT USE');
|
||||||
|
label.setAttribute('style', 'font-weight: bold; color: red; cursor: pointer');
|
||||||
|
label.onclick = function () {
|
||||||
|
Zotero.launchURL('https://www.zotero.org/support/kb/test_builds');
|
||||||
|
};
|
||||||
|
let syncStop = document.getElementById('zotero-tb-sync-stop');
|
||||||
|
syncStop.parentNode.insertBefore(label, syncStop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
Zotero.logError(e);
|
||||||
|
}
|
||||||
|
|
||||||
Zotero_Tabs.init();
|
Zotero_Tabs.init();
|
||||||
ZoteroContextPane.init();
|
ZoteroContextPane.init();
|
||||||
await ZoteroPane.initCollectionsTree();
|
await ZoteroPane.initCollectionsTree();
|
||||||
|
|
@ -1788,6 +1809,71 @@ var ZoteroPane = new function()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
this.duplicateAndConvertSelectedItem = async function () {
|
||||||
|
if (this.getSelectedItems().length != 1
|
||||||
|
|| !['book', 'bookSection'].includes(this.getSelectedItems()[0].itemType)) {
|
||||||
|
throw new Error('duplicateAndConvertSelectedItem requires a single book or bookSection to be selected');
|
||||||
|
}
|
||||||
|
|
||||||
|
let authorCreatorType = Zotero.CreatorTypes.getID('author');
|
||||||
|
let bookAuthorCreatorType = Zotero.CreatorTypes.getID('bookAuthor');
|
||||||
|
|
||||||
|
let original = this.getSelectedItems()[0];
|
||||||
|
let duplicate = await this.duplicateSelectedItem();
|
||||||
|
if (!duplicate) return null;
|
||||||
|
|
||||||
|
// TODO: Move this logic to duplicateSelectedItem() with a `targetItemType` flag to avoid
|
||||||
|
// extra saves?
|
||||||
|
if (duplicate.itemType == 'book') {
|
||||||
|
duplicate.setType(Zotero.ItemTypes.getID('bookSection'));
|
||||||
|
for (let i = 0; i < duplicate.numCreators(); i++) {
|
||||||
|
let creator = duplicate.getCreator(i);
|
||||||
|
if (creator.creatorTypeID == authorCreatorType) {
|
||||||
|
creator.creatorTypeID = bookAuthorCreatorType;
|
||||||
|
}
|
||||||
|
duplicate.setCreator(i, creator);
|
||||||
|
}
|
||||||
|
// Remove related-item relations to other book sections of this book
|
||||||
|
for (let relItemKey of [...duplicate.relatedItems]) {
|
||||||
|
let relItem = await Zotero.Items.getByLibraryAndKeyAsync(
|
||||||
|
duplicate.libraryID, relItemKey
|
||||||
|
);
|
||||||
|
if (relItem.itemType == 'bookSection'
|
||||||
|
&& relItem.getField('bookTitle') == original.getField('title')) {
|
||||||
|
duplicate.removeRelatedItem(relItem);
|
||||||
|
relItem.removeRelatedItem(duplicate);
|
||||||
|
await relItem.saveTx();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
duplicate.setField('title', false); // So bookTitle becomes title
|
||||||
|
duplicate.setType(Zotero.ItemTypes.getID('book'));
|
||||||
|
// Get creators from the original item because setType() will have changed the types
|
||||||
|
let creators = original.getCreators()
|
||||||
|
// Remove authors of the individual book section
|
||||||
|
.filter(creator => creator.creatorTypeID !== authorCreatorType);
|
||||||
|
for (let creator of creators) {
|
||||||
|
if (creator.creatorTypeID == bookAuthorCreatorType) {
|
||||||
|
creator.creatorTypeID = authorCreatorType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
duplicate.setCreators(creators);
|
||||||
|
}
|
||||||
|
|
||||||
|
duplicate.setField('abstractNote', '');
|
||||||
|
|
||||||
|
duplicate.addRelatedItem(original);
|
||||||
|
original.addRelatedItem(duplicate);
|
||||||
|
|
||||||
|
await original.saveTx({ skipDateModifiedUpdate: true });
|
||||||
|
await duplicate.saveTx();
|
||||||
|
|
||||||
|
document.getElementById('zotero-editpane-item-box').focusField('title');
|
||||||
|
return duplicate;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return whether every selected item can be deleted from the current
|
* Return whether every selected item can be deleted from the current
|
||||||
* collection context (library, trash, collection, etc.).
|
* collection context (library, trash, collection, etc.).
|
||||||
|
|
@ -1877,13 +1963,39 @@ var ZoteroPane = new function()
|
||||||
var prompt = (force && !fromMenu) ? false : toTrash;
|
var prompt = (force && !fromMenu) ? false : toTrash;
|
||||||
}
|
}
|
||||||
else if (collectionTreeRow.isCollection()) {
|
else if (collectionTreeRow.isCollection()) {
|
||||||
|
if (force) {
|
||||||
// Ignore unmodified action if only child items are selected
|
var prompt = toTrash;
|
||||||
if (!force && this.itemsView.getSelectedItems().every(item => !item.isTopLevelItem())) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// Ignore unmodified action if only child items are selected
|
||||||
|
if (this.itemsView.getSelectedItems().every(item => !item.isTopLevelItem())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var prompt = force ? toTrash : toRemove;
|
// If unmodified, recursiveCollections is true, and items are in
|
||||||
|
// descendant collections (even if also in the selected collection),
|
||||||
|
// prompt to remove from all
|
||||||
|
if (Zotero.Prefs.get('recursiveCollections')) {
|
||||||
|
let descendants = collectionTreeRow.ref.getDescendents(false, 'collection');
|
||||||
|
let inSubcollection = descendants
|
||||||
|
.some(({ id }) => this.itemsView.getSelectedItems()
|
||||||
|
.some(item => item.inCollection(id)));
|
||||||
|
if (inSubcollection) {
|
||||||
|
var prompt = {
|
||||||
|
title: Zotero.getString('pane.items.removeRecursive.title'),
|
||||||
|
text: Zotero.getString(
|
||||||
|
'pane.items.removeRecursive' + (this.itemsView.selection.count > 1 ? '.multiple' : '')
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var prompt = toRemove;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var prompt = toRemove;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (collectionTreeRow.isTrash() || collectionTreeRow.isBucket()) {
|
else if (collectionTreeRow.isTrash() || collectionTreeRow.isBucket()) {
|
||||||
var prompt = toDelete;
|
var prompt = toDelete;
|
||||||
|
|
@ -1920,8 +2032,9 @@ var ZoteroPane = new function()
|
||||||
this.deleteSelectedCollection = function (deleteItems) {
|
this.deleteSelectedCollection = function (deleteItems) {
|
||||||
var collectionTreeRow = this.getCollectionTreeRow();
|
var collectionTreeRow = this.getCollectionTreeRow();
|
||||||
|
|
||||||
// Don't allow deleting libraries
|
// Don't allow deleting libraries or My Publications
|
||||||
if (collectionTreeRow.isLibrary(true) && !collectionTreeRow.isFeed()) {
|
if (collectionTreeRow.isLibrary(true) && !collectionTreeRow.isFeed()
|
||||||
|
|| collectionTreeRow.isPublications()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2288,7 +2401,7 @@ var ZoteroPane = new function()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Zotero_File_Interface.exportItemsToClipboard(items, format.id);
|
Zotero_File_Interface.exportItemsToClipboard(items, format);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3038,7 +3151,6 @@ var ZoteroPane = new function()
|
||||||
'sep1',
|
'sep1',
|
||||||
'addNote',
|
'addNote',
|
||||||
'createNoteFromAnnotations',
|
'createNoteFromAnnotations',
|
||||||
'createNoteFromAnnotationsMenu',
|
|
||||||
'addAttachments',
|
'addAttachments',
|
||||||
'sep2',
|
'sep2',
|
||||||
'findPDF',
|
'findPDF',
|
||||||
|
|
@ -3046,6 +3158,7 @@ var ZoteroPane = new function()
|
||||||
'toggleRead',
|
'toggleRead',
|
||||||
'addToCollection',
|
'addToCollection',
|
||||||
'removeItems',
|
'removeItems',
|
||||||
|
'duplicateAndConvert',
|
||||||
'duplicateItem',
|
'duplicateItem',
|
||||||
'restoreToLibrary',
|
'restoreToLibrary',
|
||||||
'moveToTrash',
|
'moveToTrash',
|
||||||
|
|
@ -3173,12 +3286,33 @@ var ZoteroPane = new function()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// "Add Notes from Annotation" and "Find Available PDFs"
|
// "Add/Create Note from Annotations" and "Find Available PDFs"
|
||||||
if (collectionTreeRow.filesEditable
|
if (collectionTreeRow.filesEditable
|
||||||
&& !collectionTreeRow.isDuplicates()
|
&& !collectionTreeRow.isDuplicates()
|
||||||
&& !collectionTreeRow.isFeed()) {
|
&& !collectionTreeRow.isFeed()) {
|
||||||
if (items.some(item => attachmentsWithExtractableAnnotations(item).length)) {
|
if (items.some(item => attachmentsWithExtractableAnnotations(item).length)
|
||||||
|
|| items.some(item => isAttachmentWithExtractableAnnotations(item))) {
|
||||||
|
let menuitem = menu.childNodes[m.createNoteFromAnnotations];
|
||||||
show.add(m.createNoteFromAnnotations);
|
show.add(m.createNoteFromAnnotations);
|
||||||
|
let key;
|
||||||
|
// If all from a single item, show "Add Note from Annotations"
|
||||||
|
if (Zotero.Items.getTopLevel(items).length == 1) {
|
||||||
|
key = 'addNoteFromAnnotations';
|
||||||
|
menuitem.onclick = async () => {
|
||||||
|
return this.addNoteFromAnnotationsFromSelected();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// Otherwise show "Create Note from Annotations"
|
||||||
|
else {
|
||||||
|
key = 'createNoteFromAnnotations';
|
||||||
|
menuitem.onclick = async () => {
|
||||||
|
return this.createStandaloneNoteFromAnnotationsFromSelected();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
menuitem.setAttribute(
|
||||||
|
'label',
|
||||||
|
Zotero.getString('pane.items.menu.' + key)
|
||||||
|
);
|
||||||
show.add(m.sep3);
|
show.add(m.sep3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3238,43 +3372,42 @@ var ZoteroPane = new function()
|
||||||
show.add(m.sep1);
|
show.add(m.sep1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Show "Add Note from Annotations" on parent item with any extractable annotations
|
||||||
if (item.isRegularItem() && !item.isFeedItem) {
|
if (item.isRegularItem() && !item.isFeedItem) {
|
||||||
show.add(m.addNote);
|
show.add(m.addNote);
|
||||||
show.add(m.addAttachments);
|
show.add(m.addAttachments);
|
||||||
show.add(m.sep2);
|
show.add(m.sep2);
|
||||||
|
|
||||||
// Create Note from Annotations
|
let attachmentsWithAnnotations = Zotero.Items.get(item.getAttachments())
|
||||||
let popup = document.getElementById('create-note-from-annotations-popup');
|
|
||||||
popup.textContent = '';
|
|
||||||
let eligibleAttachments = Zotero.Items.get(item.getAttachments())
|
|
||||||
.filter(item => item.isPDFAttachment());
|
|
||||||
let attachmentsWithAnnotations = eligibleAttachments
|
|
||||||
.filter(item => isAttachmentWithExtractableAnnotations(item));
|
.filter(item => isAttachmentWithExtractableAnnotations(item));
|
||||||
if (attachmentsWithAnnotations.length) {
|
if (attachmentsWithAnnotations.length) {
|
||||||
// Display submenu if there's more than one PDF attachment, even if
|
show.add(m.createNoteFromAnnotations);
|
||||||
// there's only attachment with annotations, so it's clear which one
|
|
||||||
// the annotations are coming from
|
|
||||||
if (eligibleAttachments.length > 1) {
|
|
||||||
show.add(m.createNoteFromAnnotationsMenu);
|
|
||||||
for (let attachment of attachmentsWithAnnotations) {
|
|
||||||
let menuitem = document.createElement('menuitem');
|
|
||||||
menuitem.setAttribute('label', attachment.getDisplayTitle());
|
|
||||||
menuitem.onclick = () => {
|
|
||||||
ZoteroPane.createNoteFromAnnotationsForAttachment(attachment);
|
|
||||||
};
|
|
||||||
popup.appendChild(menuitem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Single attachment with annotations
|
|
||||||
else {
|
|
||||||
show.add(m.createNoteFromAnnotations);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (isAttachmentWithExtractableAnnotations(item) && !item.isTopLevelItem()) {
|
// Show "(Create|Add) Note from Annotations" on attachment with extractable annotations
|
||||||
|
else if (isAttachmentWithExtractableAnnotations(item)) {
|
||||||
show.add(m.createNoteFromAnnotations);
|
show.add(m.createNoteFromAnnotations);
|
||||||
show.add(m.sep2);
|
show.add(m.sep2);
|
||||||
}
|
}
|
||||||
|
if (show.has(m.createNoteFromAnnotations)) {
|
||||||
|
let menuitem = menu.childNodes[m.createNoteFromAnnotations];
|
||||||
|
let str;
|
||||||
|
// Show "Create" on standalone attachments
|
||||||
|
if (item.isAttachment() && item.isTopLevelItem()) {
|
||||||
|
str = 'pane.items.menu.createNoteFromAnnotations';
|
||||||
|
menuitem.onclick = async () => {
|
||||||
|
return this.createStandaloneNoteFromAnnotationsFromSelected();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// And "Add" otherwise
|
||||||
|
else {
|
||||||
|
str = 'pane.items.menu.addNoteFromAnnotations';
|
||||||
|
menuitem.onclick = async () => {
|
||||||
|
return this.addNoteFromAnnotationsFromSelected();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
menuitem.setAttribute('label', Zotero.getString(str));
|
||||||
|
}
|
||||||
|
|
||||||
if (Zotero.Attachments.canFindPDFForItem(item)) {
|
if (Zotero.Attachments.canFindPDFForItem(item)) {
|
||||||
show.add(m.findPDF);
|
show.add(m.findPDF);
|
||||||
|
|
@ -3325,6 +3458,12 @@ var ZoteroPane = new function()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!collectionTreeRow.isPublications()) {
|
else if (!collectionTreeRow.isPublications()) {
|
||||||
|
if (item.itemType == 'book' || item.itemType == 'bookSection') {
|
||||||
|
menu.childNodes[m.duplicateAndConvert].setAttribute('label', Zotero.getString('pane.items.menu.duplicateAndConvert.'
|
||||||
|
+ (item.itemType == 'book' ? 'toBookSection' : 'toBook')));
|
||||||
|
show.add(m.duplicateAndConvert);
|
||||||
|
}
|
||||||
|
|
||||||
show.add(m.duplicateItem);
|
show.add(m.duplicateItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3434,8 +3573,6 @@ var ZoteroPane = new function()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set labels, plural if necessary
|
// Set labels, plural if necessary
|
||||||
menu.childNodes[m.createNoteFromAnnotations].setAttribute('label', Zotero.getString('pane.items.menu.addNoteFromAnnotations' + multiple));
|
|
||||||
menu.childNodes[m.createNoteFromAnnotationsMenu].setAttribute('label', Zotero.getString('pane.items.menu.addNoteFromAnnotations' + multiple));
|
|
||||||
menu.childNodes[m.findPDF].setAttribute('label', Zotero.getString('pane.items.menu.findAvailablePDF' + multiple));
|
menu.childNodes[m.findPDF].setAttribute('label', Zotero.getString('pane.items.menu.findAvailablePDF' + multiple));
|
||||||
menu.childNodes[m.moveToTrash].setAttribute('label', Zotero.getString('pane.items.menu.moveToTrash' + multiple));
|
menu.childNodes[m.moveToTrash].setAttribute('label', Zotero.getString('pane.items.menu.moveToTrash' + multiple));
|
||||||
menu.childNodes[m.deleteFromLibrary].setAttribute('label', Zotero.getString('pane.items.menu.delete'));
|
menu.childNodes[m.deleteFromLibrary].setAttribute('label', Zotero.getString('pane.items.menu.delete'));
|
||||||
|
|
@ -3507,6 +3644,9 @@ var ZoteroPane = new function()
|
||||||
throw new Error('collection must be null if createNew is true');
|
throw new Error('collection must be null if createNew is true');
|
||||||
}
|
}
|
||||||
let id = await this.newCollection();
|
let id = await this.newCollection();
|
||||||
|
if (!id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
collection = Zotero.Collections.get(id);
|
collection = Zotero.Collections.get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4279,12 +4419,25 @@ var ZoteroPane = new function()
|
||||||
extraData && extraData.location,
|
extraData && extraData.location,
|
||||||
{
|
{
|
||||||
openInWindow: (event && event.shiftKey)
|
openInWindow: (event && event.shiftKey)
|
||||||
|| (extraData && extraData.forceOpenPDFInWindow)
|
|| (extraData && extraData.forceOpenPDFInWindow),
|
||||||
|
allowDuplicate: event && event.shiftKey
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// Try to open external reader to page number if specified
|
||||||
|
else {
|
||||||
|
let pageIndex = extraData?.location?.position?.pageIndex;
|
||||||
|
if (pageIndex !== undefined) {
|
||||||
|
await Zotero.OpenPDF.openToPage(
|
||||||
|
item,
|
||||||
|
parseInt(pageIndex) + 1
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
// Custom PDF handler
|
// Custom PDF handler
|
||||||
|
// TODO: Remove this and unify with Zotero.OpenPDF
|
||||||
if (pdfHandler != 'system') {
|
if (pdfHandler != 'system') {
|
||||||
try {
|
try {
|
||||||
if (await OS.File.exists(pdfHandler)) {
|
if (await OS.File.exists(pdfHandler)) {
|
||||||
|
|
@ -4319,7 +4472,7 @@ var ZoteroPane = new function()
|
||||||
let path = item.getFilePath();
|
let path = item.getFilePath();
|
||||||
if (!path) {
|
if (!path) {
|
||||||
ZoteroPane_Local.showAttachmentNotFoundDialog(
|
ZoteroPane_Local.showAttachmentNotFoundDialog(
|
||||||
item.id,
|
item,
|
||||||
path,
|
path,
|
||||||
{
|
{
|
||||||
noLocate: true,
|
noLocate: true,
|
||||||
|
|
@ -4408,7 +4561,7 @@ var ZoteroPane = new function()
|
||||||
|
|
||||||
if (isLinkedFile || !fileSyncingEnabled) {
|
if (isLinkedFile || !fileSyncingEnabled) {
|
||||||
this.showAttachmentNotFoundDialog(
|
this.showAttachmentNotFoundDialog(
|
||||||
itemID,
|
item,
|
||||||
path,
|
path,
|
||||||
{
|
{
|
||||||
noLocate: noLocateOnMissing,
|
noLocate: noLocateOnMissing,
|
||||||
|
|
@ -4434,7 +4587,7 @@ var ZoteroPane = new function()
|
||||||
|
|
||||||
if (!await item.getFilePathAsync()) {
|
if (!await item.getFilePathAsync()) {
|
||||||
ZoteroPane_Local.showAttachmentNotFoundDialog(
|
ZoteroPane_Local.showAttachmentNotFoundDialog(
|
||||||
item.id,
|
item,
|
||||||
path,
|
path,
|
||||||
{
|
{
|
||||||
noLocate: noLocateOnMissing,
|
noLocate: noLocateOnMissing,
|
||||||
|
|
@ -4501,7 +4654,7 @@ var ZoteroPane = new function()
|
||||||
|
|
||||||
if (!fileExists) {
|
if (!fileExists) {
|
||||||
this.showAttachmentNotFoundDialog(
|
this.showAttachmentNotFoundDialog(
|
||||||
attachment.id,
|
attachment,
|
||||||
path,
|
path,
|
||||||
{
|
{
|
||||||
noLocate: noLocateOnMissing,
|
noLocate: noLocateOnMissing,
|
||||||
|
|
@ -4647,9 +4800,13 @@ var ZoteroPane = new function()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
this.showAttachmentNotFoundDialog = function (itemID, path, options = {}) {
|
this.showAttachmentNotFoundDialog = async function (item, path, options = {}) {
|
||||||
var { noLocate, notOnServer, linkedFile } = options;
|
var { noLocate, notOnServer, linkedFile } = options;
|
||||||
|
|
||||||
|
if (item.isLinkedFileAttachment() && await this.checkForLinkedFilesToRelink(item)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var title = Zotero.getString('pane.item.attachments.fileNotFound.title');
|
var title = Zotero.getString('pane.item.attachments.fileNotFound.title');
|
||||||
var text = Zotero.getString(
|
var text = Zotero.getString(
|
||||||
'pane.item.attachments.fileNotFound.text1' + (path ? '.path' : '')
|
'pane.item.attachments.fileNotFound.text1' + (path ? '.path' : '')
|
||||||
|
|
@ -4664,7 +4821,7 @@ var ZoteroPane = new function()
|
||||||
),
|
),
|
||||||
[ZOTERO_CONFIG.CLIENT_NAME, ZOTERO_CONFIG.DOMAIN_NAME]
|
[ZOTERO_CONFIG.CLIENT_NAME, ZOTERO_CONFIG.DOMAIN_NAME]
|
||||||
);
|
);
|
||||||
var supportURL = options.linkedFile
|
var supportURL = linkedFile
|
||||||
? 'https://www.zotero.org/support/kb/missing_linked_file'
|
? 'https://www.zotero.org/support/kb/missing_linked_file'
|
||||||
: 'https://www.zotero.org/support/kb/files_not_syncing';
|
: 'https://www.zotero.org/support/kb/files_not_syncing';
|
||||||
|
|
||||||
|
|
@ -4702,7 +4859,7 @@ var ZoteroPane = new function()
|
||||||
);
|
);
|
||||||
|
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
this.relinkAttachment(itemID);
|
this.relinkAttachment(item.id);
|
||||||
}
|
}
|
||||||
else if (index == 2) {
|
else if (index == 2) {
|
||||||
this.loadURI(supportURL, { metaKey: true, shiftKey: true });
|
this.loadURI(supportURL, { metaKey: true, shiftKey: true });
|
||||||
|
|
@ -4710,6 +4867,70 @@ var ZoteroPane = new function()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prompt the user to relink one or all of the attachment files found in
|
||||||
|
* the LABD.
|
||||||
|
*
|
||||||
|
* @param {Zotero.Item} item
|
||||||
|
* @param {String} path Path to the file matching `item`
|
||||||
|
* @param {Number} numOthers If zero, "Relink All" option is not offered
|
||||||
|
* @return {'one' | 'all' | 'manual' | 'cancel'}
|
||||||
|
*/
|
||||||
|
this.showLinkedFileFoundAutomaticallyDialog = function (item, path, numOthers) {
|
||||||
|
let ps = Services.prompt;
|
||||||
|
|
||||||
|
let title = Zotero.getString('pane.item.attachments.autoRelink.title');
|
||||||
|
let text = Zotero.getString('pane.item.attachments.autoRelink.text1') + '\n\n'
|
||||||
|
+ Zotero.getString('pane.item.attachments.autoRelink.text2', item.getFilePath()) + '\n\n'
|
||||||
|
+ Zotero.getString('pane.item.attachments.autoRelink.text3', path) + '\n\n'
|
||||||
|
+ Zotero.getString('pane.item.attachments.autoRelink.text4', Zotero.appName);
|
||||||
|
let buttonFlags = ps.BUTTON_POS_0 * ps.BUTTON_TITLE_IS_STRING
|
||||||
|
+ ps.BUTTON_POS_1 * ps.BUTTON_TITLE_CANCEL
|
||||||
|
+ ps.BUTTON_POS_2 * ps.BUTTON_TITLE_IS_STRING;
|
||||||
|
let index = ps.confirmEx(null,
|
||||||
|
title,
|
||||||
|
text,
|
||||||
|
buttonFlags,
|
||||||
|
Zotero.getString('pane.item.attachments.autoRelink.relink'),
|
||||||
|
null,
|
||||||
|
Zotero.getString('pane.item.attachments.autoRelink.locateManually'),
|
||||||
|
null, {}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (index == 1) {
|
||||||
|
// Cancel
|
||||||
|
return 'cancel';
|
||||||
|
}
|
||||||
|
else if (index == 2) {
|
||||||
|
// Locate Manually...
|
||||||
|
return 'manual';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Relink
|
||||||
|
if (!numOthers) {
|
||||||
|
return 'one';
|
||||||
|
}
|
||||||
|
|
||||||
|
title = Zotero.getString('pane.item.attachments.autoRelinkOthers.title');
|
||||||
|
text = Zotero.getString('pane.item.attachments.autoRelinkOthers.text', numOthers, numOthers);
|
||||||
|
buttonFlags = ps.BUTTON_POS_0 * ps.BUTTON_TITLE_IS_STRING
|
||||||
|
+ ps.BUTTON_POS_1 * ps.BUTTON_TITLE_CANCEL;
|
||||||
|
index = ps.confirmEx(null,
|
||||||
|
title,
|
||||||
|
text,
|
||||||
|
buttonFlags,
|
||||||
|
Zotero.getString(
|
||||||
|
numOthers == 1
|
||||||
|
? 'pane.item.attachments.autoRelink.relink'
|
||||||
|
: 'pane.item.attachments.autoRelink.relinkAll'
|
||||||
|
),
|
||||||
|
null, null, null, {}
|
||||||
|
);
|
||||||
|
|
||||||
|
return index == 0 ? 'all' : 'one';
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
this.syncAlert = function (e) {
|
this.syncAlert = function (e) {
|
||||||
e = Zotero.Sync.Runner.parseError(e);
|
e = Zotero.Sync.Runner.parseError(e);
|
||||||
var ps = Services.prompt;
|
var ps = Services.prompt;
|
||||||
|
|
@ -4817,14 +5038,21 @@ var ZoteroPane = new function()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
this.createNoteFromAnnotationsForAttachment = async function (attachment, { skipSelect } = {}) {
|
this.addNoteFromAnnotationsForAttachment = async function (attachment, { skipSelect } = {}) {
|
||||||
if (!this.canEdit()) {
|
if (!this.canEdit()) {
|
||||||
this.displayCannotEditLibraryMessage();
|
this.displayCannotEditLibraryMessage();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await Zotero.PDFWorker.import(attachment.id, true);
|
await Zotero.PDFWorker.import(attachment.id, true);
|
||||||
|
var annotations = attachment.getAnnotations().filter(x => x.annotationType != 'ink');
|
||||||
|
if (!annotations.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
var note = await Zotero.EditorInstance.createNoteFromAnnotations(
|
var note = await Zotero.EditorInstance.createNoteFromAnnotations(
|
||||||
attachment.getAnnotations().filter(x => x.annotationType != 'ink'), attachment.parentID
|
annotations,
|
||||||
|
{
|
||||||
|
parentID: attachment.parentID
|
||||||
|
}
|
||||||
);
|
);
|
||||||
if (!skipSelect) {
|
if (!skipSelect) {
|
||||||
await this.selectItem(note.id);
|
await this.selectItem(note.id);
|
||||||
|
|
@ -4833,7 +5061,81 @@ var ZoteroPane = new function()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
this.createNoteFromAnnotationsFromSelected = async function () {
|
/**
|
||||||
|
* Add a single child note with the annotations from all selected items, including from all
|
||||||
|
* child attachments of a selected regular item
|
||||||
|
*
|
||||||
|
* Selected items must all have the same top-level item
|
||||||
|
*/
|
||||||
|
this.addNoteFromAnnotationsFromSelected = async function () {
|
||||||
|
if (!this.canEdit()) {
|
||||||
|
this.displayCannotEditLibraryMessage();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var items = this.getSelectedItems();
|
||||||
|
var topLevelItems = [...new Set(Zotero.Items.getTopLevel(items))];
|
||||||
|
if (topLevelItems.length > 1) {
|
||||||
|
throw new Error("Can't create child attachment from different top-level items");
|
||||||
|
}
|
||||||
|
var topLevelItem = topLevelItems[0];
|
||||||
|
if (!topLevelItem.isRegularItem()) {
|
||||||
|
throw new Error("Can't add note to standalone attachment");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore top-level item if specific child items are also selected
|
||||||
|
if (items.length > 1) {
|
||||||
|
items = items.filter(item => !item.isRegularItem());
|
||||||
|
}
|
||||||
|
|
||||||
|
var attachments = [];
|
||||||
|
for (let item of items) {
|
||||||
|
if (item.isRegularItem()) {
|
||||||
|
// Find all child items with extractable annotations
|
||||||
|
attachments.push(
|
||||||
|
...Zotero.Items.get(item.getAttachments())
|
||||||
|
.filter(item => isAttachmentWithExtractableAnnotations(item))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (isAttachmentWithExtractableAnnotations(item)) {
|
||||||
|
attachments.push(item);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!attachments.length) {
|
||||||
|
Zotero.debug("No attachments found", 2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var annotations = [];
|
||||||
|
for (let attachment of attachments) {
|
||||||
|
try {
|
||||||
|
await Zotero.PDFWorker.import(attachment.id, true);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
Zotero.logError(e);
|
||||||
|
}
|
||||||
|
annotations.push(...attachment.getAnnotations().filter(x => x.annotationType != 'ink'));
|
||||||
|
}
|
||||||
|
var note = await Zotero.EditorInstance.createNoteFromAnnotations(
|
||||||
|
annotations,
|
||||||
|
{
|
||||||
|
parentID: topLevelItem.id
|
||||||
|
}
|
||||||
|
);
|
||||||
|
await this.selectItem(note.id);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create separate child notes for each selected item, including all child attachments of
|
||||||
|
* selected regular items
|
||||||
|
*
|
||||||
|
* No longer exposed via UI
|
||||||
|
*/
|
||||||
|
this.addNotesFromAnnotationsFromSelected = async function () {
|
||||||
if (!this.canEdit()) {
|
if (!this.canEdit()) {
|
||||||
this.displayCannotEditLibraryMessage();
|
this.displayCannotEditLibraryMessage();
|
||||||
return;
|
return;
|
||||||
|
|
@ -4859,16 +5161,77 @@ var ZoteroPane = new function()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (let attachment of attachments) {
|
for (let attachment of attachments) {
|
||||||
let note = await this.createNoteFromAnnotationsForAttachment(
|
let note = await this.addNoteFromAnnotationsForAttachment(
|
||||||
attachment,
|
attachment,
|
||||||
{ skipSelect: true }
|
{ skipSelect: true }
|
||||||
);
|
);
|
||||||
itemIDsToSelect.push(note.id);
|
if (note) {
|
||||||
|
itemIDsToSelect.push(note.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await this.selectItems(itemIDsToSelect);
|
await this.selectItems(itemIDsToSelect);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
this.createStandaloneNoteFromAnnotationsFromSelected = async function () {
|
||||||
|
if (!this.canEdit()) {
|
||||||
|
this.displayCannotEditLibraryMessage();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var items = this.getSelectedItems();
|
||||||
|
|
||||||
|
// Ignore selected top-level items if any descendant items are also selected
|
||||||
|
var topLevelOfSelectedDescendants = new Set();
|
||||||
|
for (let item of items) {
|
||||||
|
if (!item.isTopLevelItem()) {
|
||||||
|
topLevelOfSelectedDescendants.add(item.topLevelItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
items = items.filter(item => !topLevelOfSelectedDescendants.has(item));
|
||||||
|
|
||||||
|
var annotations = [];
|
||||||
|
for (let item of items) {
|
||||||
|
let attachments = [];
|
||||||
|
if (item.isRegularItem()) {
|
||||||
|
// Find all child attachments with extractable annotations
|
||||||
|
attachments.push(
|
||||||
|
...Zotero.Items.get(item.getAttachments())
|
||||||
|
.filter(item => isAttachmentWithExtractableAnnotations(item))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (isAttachmentWithExtractableAnnotations(item)) {
|
||||||
|
attachments.push(item);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (let attachment of attachments) {
|
||||||
|
try {
|
||||||
|
await Zotero.PDFWorker.import(attachment.id, true);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
Zotero.logError(e);
|
||||||
|
}
|
||||||
|
annotations.push(...attachment.getAnnotations().filter(x => x.annotationType != 'ink'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!annotations.length) {
|
||||||
|
Zotero.debug("No annotations found", 2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var note = await Zotero.EditorInstance.createNoteFromAnnotations(
|
||||||
|
annotations,
|
||||||
|
{
|
||||||
|
collectionID: this.getSelectedCollection(true)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
await this.selectItem(note.id);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
this.createEmptyParent = async function (item) {
|
this.createEmptyParent = async function (item) {
|
||||||
await Zotero.DB.executeTransaction(async function () {
|
await Zotero.DB.executeTransaction(async function () {
|
||||||
// TODO: remove once there are no top-level web attachments
|
// TODO: remove once there are no top-level web attachments
|
||||||
|
|
@ -5064,6 +5427,120 @@ var ZoteroPane = new function()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to find a file in the LABD matching the passed attachment
|
||||||
|
* by searching successive subdirectories. Prompt the user if a match is
|
||||||
|
* found and offer to relink one or all matching files in the directory.
|
||||||
|
* The user can also choose to relink manually, which opens a file picker.
|
||||||
|
*
|
||||||
|
* If the synced path is 'C:\Users\user\Documents\Dissertation\Files\Paper.pdf',
|
||||||
|
* the LABD is '/Users/user/Documents', and the (not yet known) correct local
|
||||||
|
* path is '/Users/user/Documents/Dissertation/Files/Paper.pdf', check:
|
||||||
|
*
|
||||||
|
* 1. /Users/user/Documents/Users/user/Documents/Dissertation/Files/Paper.pdf
|
||||||
|
* 2. /Users/user/Documents/user/Documents/Dissertation/Files/Paper.pdf
|
||||||
|
* 3. /Users/user/Documents/Documents/Dissertation/Files/Paper.pdf
|
||||||
|
* 4. /Users/user/Documents/Dissertation/Files/Paper.pdf
|
||||||
|
*
|
||||||
|
* If line 4 had not been the correct local path (in other words, if no file
|
||||||
|
* existed at that path), we would have continued on to check
|
||||||
|
* '/Users/user/Documents/Dissertation/Paper.pdf'. If that did not match,
|
||||||
|
* with no more segments in the synced path to drop, we would have given up.
|
||||||
|
*
|
||||||
|
* Once we find the file, check for other linked files beginning with
|
||||||
|
* C:\Users\user\Documents\Dissertation\Files and see if they exist relative
|
||||||
|
* to /Users/user/Documents/Dissertation/Files, and prompt to relink them
|
||||||
|
* all if so.
|
||||||
|
*
|
||||||
|
* @param {Zotero.Item} item
|
||||||
|
* @return {Promise<Boolean>} True if relinked successfully or canceled
|
||||||
|
*/
|
||||||
|
this.checkForLinkedFilesToRelink = async function (item) {
|
||||||
|
Zotero.debug('Attempting to relink automatically');
|
||||||
|
|
||||||
|
let basePath = Zotero.Prefs.get('baseAttachmentPath');
|
||||||
|
if (!basePath) {
|
||||||
|
Zotero.debug('No LABD');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Zotero.debug('LABD path: ' + basePath);
|
||||||
|
|
||||||
|
let syncedPath = item.getFilePath();
|
||||||
|
if (!syncedPath) {
|
||||||
|
Zotero.debug('No synced path');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
syncedPath = Zotero.File.normalizeToUnix(syncedPath);
|
||||||
|
Zotero.debug('Synced path: ' + syncedPath);
|
||||||
|
|
||||||
|
if (Zotero.File.directoryContains(basePath, syncedPath)) {
|
||||||
|
// Already in the LABD - nothing to do
|
||||||
|
Zotero.debug('Synced path is already within LABD');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We can't use OS.Path.dirname because that function expects paths valid for the current platform...
|
||||||
|
// but we can't normalize first because we're going to be comparing it to other un-normalized paths
|
||||||
|
let unNormalizedDirname = item.getFilePath();
|
||||||
|
let lastSlash = Math.max(
|
||||||
|
unNormalizedDirname.lastIndexOf('/'),
|
||||||
|
unNormalizedDirname.lastIndexOf('\\')
|
||||||
|
);
|
||||||
|
if (lastSlash != -1) {
|
||||||
|
unNormalizedDirname = unNormalizedDirname.substring(0, lastSlash + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
let parts = OS.Path.split(syncedPath).components;
|
||||||
|
for (let segmentsToDrop = 0; segmentsToDrop < parts.length; segmentsToDrop++) {
|
||||||
|
let correctedPath = OS.Path.join(basePath, ...parts.slice(segmentsToDrop));
|
||||||
|
|
||||||
|
if (!(await OS.File.exists(correctedPath))) {
|
||||||
|
Zotero.debug('Does not exist: ' + correctedPath);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Zotero.debug('Exists! ' + correctedPath);
|
||||||
|
|
||||||
|
let otherUnlinked = await Zotero.Items.findMissingLinkedFiles(
|
||||||
|
item.libraryID,
|
||||||
|
unNormalizedDirname
|
||||||
|
);
|
||||||
|
let othersToRelink = new Map();
|
||||||
|
for (let otherItem of otherUnlinked) {
|
||||||
|
if (otherItem.id === item.id) continue;
|
||||||
|
let otherParts = otherItem.getFilePath()
|
||||||
|
.split(/[/\\]/)
|
||||||
|
// Slice as much off the beginning as when creating correctedPath
|
||||||
|
.slice(segmentsToDrop);
|
||||||
|
if (!otherParts.length) continue;
|
||||||
|
let otherCorrectedPath = OS.Path.join(basePath, ...otherParts);
|
||||||
|
if (await OS.File.exists(otherCorrectedPath)) {
|
||||||
|
othersToRelink.set(otherItem, otherCorrectedPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let choice = this.showLinkedFileFoundAutomaticallyDialog(item, correctedPath, othersToRelink.size);
|
||||||
|
switch (choice) {
|
||||||
|
case 'one':
|
||||||
|
await item.relinkAttachmentFile(correctedPath);
|
||||||
|
return true;
|
||||||
|
case 'all':
|
||||||
|
await item.relinkAttachmentFile(correctedPath);
|
||||||
|
await Promise.all([...othersToRelink]
|
||||||
|
.map(([i, p]) => i.relinkAttachmentFile(p)));
|
||||||
|
return true;
|
||||||
|
case 'manual':
|
||||||
|
await this.relinkAttachment(item.id);
|
||||||
|
return true;
|
||||||
|
case 'cancel':
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Zotero.debug('No segments left to drop; match not found in LABD');
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
this.relinkAttachment = async function (itemID) {
|
this.relinkAttachment = async function (itemID) {
|
||||||
if (!this.canEdit()) {
|
if (!this.canEdit()) {
|
||||||
this.displayCannotEditLibraryMessage();
|
this.displayCannotEditLibraryMessage();
|
||||||
|
|
@ -5087,7 +5564,13 @@ var ZoteroPane = new function()
|
||||||
|
|
||||||
var dir = await Zotero.File.getClosestDirectory(file);
|
var dir = await Zotero.File.getClosestDirectory(file);
|
||||||
if (dir) {
|
if (dir) {
|
||||||
fp.displayDirectory = dir;
|
try {
|
||||||
|
fp.displayDirectory = dir;
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
// Directory is invalid; ignore and go with the home directory
|
||||||
|
fp.displayDirectory = OS.Constants.Path.homeDir;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fp.appendFilters(fp.filterAll);
|
fp.appendFilters(fp.filterAll);
|
||||||
|
|
|
||||||
|
|
@ -293,11 +293,7 @@
|
||||||
<!-- with icon: <menuitem class="menuitem-iconic" id="zotero-menuitem-note" label="&zotero.items.menu.attach.note;" oncommand="ZoteroPane_Local.newNote(false, this.parentNode.getAttribute('itemID'))"/>-->
|
<!-- with icon: <menuitem class="menuitem-iconic" id="zotero-menuitem-note" label="&zotero.items.menu.attach.note;" oncommand="ZoteroPane_Local.newNote(false, this.parentNode.getAttribute('itemID'))"/>-->
|
||||||
<menuitem class="menuitem-iconic zotero-menuitem-attach-note" label="&zotero.items.menu.attach.note;" oncommand="ZoteroPane_Local.newNote(false, this.parentNode.getAttribute('itemKey'))"/>
|
<menuitem class="menuitem-iconic zotero-menuitem-attach-note" label="&zotero.items.menu.attach.note;" oncommand="ZoteroPane_Local.newNote(false, this.parentNode.getAttribute('itemKey'))"/>
|
||||||
|
|
||||||
<menuitem class="menuitem-iconic zotero-menuitem-create-note-from-annotations"
|
<menuitem class="menuitem-iconic zotero-menuitem-create-note-from-annotations"/>
|
||||||
oncommand="ZoteroPane.createNoteFromAnnotationsFromSelected()"/>
|
|
||||||
<menu class="menuitem-iconic zotero-menuitem-create-note-from-annotations">
|
|
||||||
<menupopup id="create-note-from-annotations-popup"/>
|
|
||||||
</menu>
|
|
||||||
|
|
||||||
<menu class="menu-iconic zotero-menuitem-attach" label="&zotero.items.menu.attach;">
|
<menu class="menu-iconic zotero-menuitem-attach" label="&zotero.items.menu.attach;">
|
||||||
<menupopup id="zotero-add-attachment-popup">
|
<menupopup id="zotero-add-attachment-popup">
|
||||||
|
|
@ -317,6 +313,7 @@
|
||||||
</menupopup>
|
</menupopup>
|
||||||
</menu>
|
</menu>
|
||||||
<menuitem class="menuitem-iconic zotero-menuitem-remove-items" oncommand="ZoteroPane_Local.deleteSelectedItems();"/>
|
<menuitem class="menuitem-iconic zotero-menuitem-remove-items" oncommand="ZoteroPane_Local.deleteSelectedItems();"/>
|
||||||
|
<menuitem class="menuitem-iconic zotero-menuitem-duplicate-and-convert" oncommand="ZoteroPane_Local.duplicateAndConvertSelectedItem();"/>
|
||||||
<menuitem class="menuitem-iconic zotero-menuitem-duplicate-item" label="&zotero.items.menu.duplicateItem;" oncommand="ZoteroPane_Local.duplicateSelectedItem().done();"/>
|
<menuitem class="menuitem-iconic zotero-menuitem-duplicate-item" label="&zotero.items.menu.duplicateItem;" oncommand="ZoteroPane_Local.duplicateSelectedItem().done();"/>
|
||||||
<menuitem class="menuitem-iconic zotero-menuitem-restore-to-library" label="&zotero.items.menu.restoreToLibrary;" oncommand="ZoteroPane_Local.restoreSelectedItems();"/>
|
<menuitem class="menuitem-iconic zotero-menuitem-restore-to-library" label="&zotero.items.menu.restoreToLibrary;" oncommand="ZoteroPane_Local.restoreSelectedItems();"/>
|
||||||
<menuitem class="menuitem-iconic zotero-menuitem-move-to-trash" oncommand="ZoteroPane_Local.deleteSelectedItems(true, true);"/>
|
<menuitem class="menuitem-iconic zotero-menuitem-move-to-trash" oncommand="ZoteroPane_Local.deleteSelectedItems(true, true);"/>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<!ENTITY styles.preview "Zotero Style Preview">
|
<!ENTITY styles.preview "Zotero Style Preview">
|
||||||
|
|
||||||
<!ENTITY styles.preview.citationFormat "Citation Format:">
|
<!ENTITY styles.preview.citationFormat "Citation Format:">
|
||||||
<!ENTITY styles.preview.citationFormat.all "all">
|
<!ENTITY styles.preview.citationFormat.all "alles">
|
||||||
<!ENTITY styles.preview.citationFormat.author "author">
|
<!ENTITY styles.preview.citationFormat.author "author">
|
||||||
<!ENTITY styles.preview.citationFormat.authorDate "author-date">
|
<!ENTITY styles.preview.citationFormat.authorDate "author-date">
|
||||||
<!ENTITY styles.preview.citationFormat.label "label">
|
<!ENTITY styles.preview.citationFormat.label "label">
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@
|
||||||
<!ENTITY zotero.items.itemType "Tipe item">
|
<!ENTITY zotero.items.itemType "Tipe item">
|
||||||
<!ENTITY zotero.items.creator_column "Skepper">
|
<!ENTITY zotero.items.creator_column "Skepper">
|
||||||
<!ENTITY zotero.items.year_column "Jaar">
|
<!ENTITY zotero.items.year_column "Jaar">
|
||||||
<!ENTITY zotero.items.dateModified_column "Date Modified">
|
<!ENTITY zotero.items.dateModified_column "Datum gewysig">
|
||||||
<!ENTITY zotero.items.moreColumns.label "More Columns">
|
<!ENTITY zotero.items.moreColumns.label "More Columns">
|
||||||
<!ENTITY zotero.items.restoreColumnOrder.label "Restore Column Order">
|
<!ENTITY zotero.items.restoreColumnOrder.label "Restore Column Order">
|
||||||
|
|
||||||
|
|
@ -129,7 +129,7 @@
|
||||||
<!ENTITY zotero.toolbar.attachment.weblink "Save Link to Current Page">
|
<!ENTITY zotero.toolbar.attachment.weblink "Save Link to Current Page">
|
||||||
<!ENTITY zotero.toolbar.attachment.snapshot "Take Snapshot of Current Page">
|
<!ENTITY zotero.toolbar.attachment.snapshot "Take Snapshot of Current Page">
|
||||||
<!ENTITY zotero.toolbar.context.item "Item">
|
<!ENTITY zotero.toolbar.context.item "Item">
|
||||||
<!ENTITY zotero.toolbar.context.notes "Notes">
|
<!ENTITY zotero.toolbar.context.notes "Notas">
|
||||||
|
|
||||||
<!ENTITY zotero.tagSelector.noTagsToDisplay "No tags to display">
|
<!ENTITY zotero.tagSelector.noTagsToDisplay "No tags to display">
|
||||||
<!ENTITY zotero.tagSelector.loadingTags "Loading tags…">
|
<!ENTITY zotero.tagSelector.loadingTags "Loading tags…">
|
||||||
|
|
@ -148,7 +148,7 @@
|
||||||
<!ENTITY zotero.tagColorChooser.removeColor "Remove Color">
|
<!ENTITY zotero.tagColorChooser.removeColor "Remove Color">
|
||||||
|
|
||||||
<!ENTITY zotero.lookup.description "Enter ISBNs, DOIs, PMIDs, arXiv IDs, or ADS Bibcodes to add to your library:">
|
<!ENTITY zotero.lookup.description "Enter ISBNs, DOIs, PMIDs, arXiv IDs, or ADS Bibcodes to add to your library:">
|
||||||
<!ENTITY zotero.lookup.button.search "Search">
|
<!ENTITY zotero.lookup.button.search "Soek">
|
||||||
|
|
||||||
<!ENTITY zotero.createParent.title "Create Parent Item">
|
<!ENTITY zotero.createParent.title "Create Parent Item">
|
||||||
<!ENTITY zotero.createParent.button.manual "Manual Entry">
|
<!ENTITY zotero.createParent.button.manual "Manual Entry">
|
||||||
|
|
@ -311,8 +311,6 @@
|
||||||
<!ENTITY zotero.pdfReader.lastPage "Last Page">
|
<!ENTITY zotero.pdfReader.lastPage "Last Page">
|
||||||
<!ENTITY zotero.pdfReader.back "Back">
|
<!ENTITY zotero.pdfReader.back "Back">
|
||||||
<!ENTITY zotero.pdfReader.forward "Forward">
|
<!ENTITY zotero.pdfReader.forward "Forward">
|
||||||
<!ENTITY zotero.pdfReader.rotateClockwise "Rotate Clockwise">
|
|
||||||
<!ENTITY zotero.pdfReader.rotateCounterclockwise "Rotate Counterclockwise">
|
|
||||||
<!ENTITY zotero.pdfReader.handTool "Hand Tool">
|
<!ENTITY zotero.pdfReader.handTool "Hand Tool">
|
||||||
<!ENTITY zotero.pdfReader.verticalScrolling "Vertical Scrolling">
|
<!ENTITY zotero.pdfReader.verticalScrolling "Vertical Scrolling">
|
||||||
<!ENTITY zotero.pdfReader.horizontalScrolling "Horizontal Scrolling">
|
<!ENTITY zotero.pdfReader.horizontalScrolling "Horizontal Scrolling">
|
||||||
|
|
@ -325,4 +323,9 @@
|
||||||
<!ENTITY zotero.pdfReader.zoomAuto "Automatically Resize">
|
<!ENTITY zotero.pdfReader.zoomAuto "Automatically Resize">
|
||||||
<!ENTITY zotero.pdfReader.zoomPageWidth "Zoom to Page Width">
|
<!ENTITY zotero.pdfReader.zoomPageWidth "Zoom to Page Width">
|
||||||
<!ENTITY zotero.pdfReader.zoomPageHeight "Zoom to Page Height">
|
<!ENTITY zotero.pdfReader.zoomPageHeight "Zoom to Page Height">
|
||||||
|
<!ENTITY zotero.pdfReader.splitVertically "Split Vertically">
|
||||||
|
<!ENTITY zotero.pdfReader.splitHorizontally "Split Horizontally">
|
||||||
<!ENTITY zotero.pdfReader.transferFromPDF "Import Annotations…">
|
<!ENTITY zotero.pdfReader.transferFromPDF "Import Annotations…">
|
||||||
|
<!ENTITY zotero.pdfReader.rotatePageLeft "Rotate Page Left">
|
||||||
|
<!ENTITY zotero.pdfReader.rotatePageRight "Rotate Page Right">
|
||||||
|
<!ENTITY zotero.pdfReader.rotatePage180 "Rotate Page 180°">
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,8 @@ general.unknownErrorOccurred=An unknown error occurred.
|
||||||
general.invalidResponseServer=Invalid response from server.
|
general.invalidResponseServer=Invalid response from server.
|
||||||
general.tryAgainLater=Please try again in a few minutes.
|
general.tryAgainLater=Please try again in a few minutes.
|
||||||
general.serverError=The server returned an error. Please try again.
|
general.serverError=The server returned an error. Please try again.
|
||||||
general.pleaseRestart=Please restart %S.
|
general.pleaseRestart=Please restart Firefox.
|
||||||
general.pleaseRestartAndTryAgain=Please restart %S and try again.
|
general.pleaseRestartAndTryAgain=Please restart Firefox and try again.
|
||||||
general.checkForUpdate=Check for Update
|
general.checkForUpdate=Check for Update
|
||||||
general.checkForUpdates=Check for Updates
|
general.checkForUpdates=Check for Updates
|
||||||
general.actionCannotBeUndone=This action cannot be undone.
|
general.actionCannotBeUndone=This action cannot be undone.
|
||||||
|
|
@ -40,10 +40,10 @@ general.and=and
|
||||||
general.etAl=et al.
|
general.etAl=et al.
|
||||||
general.accessDenied=Access Denied
|
general.accessDenied=Access Denied
|
||||||
general.permissionDenied=Permission Denied
|
general.permissionDenied=Permission Denied
|
||||||
general.character.singular=character
|
general.character.singular=karakter
|
||||||
general.character.plural=characters
|
general.character.plural=karakters
|
||||||
general.create=Create
|
general.create=Create
|
||||||
general.delete=Delete
|
general.delete=Skrap
|
||||||
general.remove=Remove
|
general.remove=Remove
|
||||||
general.import=Import
|
general.import=Import
|
||||||
general.export=Export
|
general.export=Export
|
||||||
|
|
@ -76,7 +76,7 @@ general.continue=Continue
|
||||||
general.copy=Copy
|
general.copy=Copy
|
||||||
general.copyToClipboard=Copy to Clipboard
|
general.copyToClipboard=Copy to Clipboard
|
||||||
general.cancel=Cancel
|
general.cancel=Cancel
|
||||||
general.clear=Clear
|
general.clear=Skoon
|
||||||
general.processing=Processing
|
general.processing=Processing
|
||||||
general.finished=Finished
|
general.finished=Finished
|
||||||
general.submitted=Submitted
|
general.submitted=Submitted
|
||||||
|
|
@ -92,6 +92,7 @@ general.custom=Custom
|
||||||
general.loading=Loading…
|
general.loading=Loading…
|
||||||
general.richText=Rich Text
|
general.richText=Rich Text
|
||||||
general.clearSelection=Clear Selection
|
general.clearSelection=Clear Selection
|
||||||
|
general.insert=Insert
|
||||||
|
|
||||||
general.yellow=Yellow
|
general.yellow=Yellow
|
||||||
general.red=Red
|
general.red=Red
|
||||||
|
|
@ -114,6 +115,7 @@ about.getInvolved=Want to help? [Get involved] today!
|
||||||
punctuation.openingQMark=“
|
punctuation.openingQMark=“
|
||||||
punctuation.closingQMark=”
|
punctuation.closingQMark=”
|
||||||
punctuation.colon=:
|
punctuation.colon=:
|
||||||
|
punctuation.colon.withString=%S:
|
||||||
punctuation.ellipsis=…
|
punctuation.ellipsis=…
|
||||||
|
|
||||||
install.quickStartGuide=Quick Start Guide
|
install.quickStartGuide=Quick Start Guide
|
||||||
|
|
@ -318,7 +320,7 @@ pane.items.attach.link.uri.file=To attach a link to a file, please use “%S”.
|
||||||
pane.items.trash.title=Move to Trash
|
pane.items.trash.title=Move to Trash
|
||||||
pane.items.trash=Are you sure you want to move the selected item to the Trash?
|
pane.items.trash=Are you sure you want to move the selected item to the Trash?
|
||||||
pane.items.trash.multiple=Are you sure you want to move the selected items to the Trash?
|
pane.items.trash.multiple=Are you sure you want to move the selected items to the Trash?
|
||||||
pane.items.delete.title=Delete
|
pane.items.delete.title=Skrap
|
||||||
pane.items.delete=Are you sure you want to delete the selected item?
|
pane.items.delete=Are you sure you want to delete the selected item?
|
||||||
pane.items.delete.multiple=Are you sure you want to delete the selected items?
|
pane.items.delete.multiple=Are you sure you want to delete the selected items?
|
||||||
pane.items.remove.title=Remove from Collection
|
pane.items.remove.title=Remove from Collection
|
||||||
|
|
@ -327,8 +329,11 @@ pane.items.remove.multiple=Are you sure you want to remove the selected items fr
|
||||||
pane.items.removeFromPublications.title=Remove from My Publications
|
pane.items.removeFromPublications.title=Remove from My Publications
|
||||||
pane.items.removeFromPublications=Are you sure you want to remove the selected item from My Publications?
|
pane.items.removeFromPublications=Are you sure you want to remove the selected item from My Publications?
|
||||||
pane.items.removeFromPublications.multiple=Are you sure you want to remove the selected items from My Publications?
|
pane.items.removeFromPublications.multiple=Are you sure you want to remove the selected items from My Publications?
|
||||||
|
pane.items.removeRecursive.title=Remove from Collection and Subcollections
|
||||||
|
pane.items.removeRecursive=Are you sure you want to remove the selected item from this collection and all subcollections?
|
||||||
|
pane.items.removeRecursive.multiple=Are you sure you want to remove the selected items from this collection and all subcollections?
|
||||||
pane.items.menu.addNoteFromAnnotations=Add Note from Annotations
|
pane.items.menu.addNoteFromAnnotations=Add Note from Annotations
|
||||||
pane.items.menu.addNoteFromAnnotations.multiple=Add Notes from Annotations
|
pane.items.menu.createNoteFromAnnotations=Create Note from Annotations
|
||||||
pane.items.menu.findAvailablePDF=Find Available PDF
|
pane.items.menu.findAvailablePDF=Find Available PDF
|
||||||
pane.items.menu.findAvailablePDF.multiple=Find Available PDFs
|
pane.items.menu.findAvailablePDF.multiple=Find Available PDFs
|
||||||
pane.items.menu.addToCollection=Add to Collection
|
pane.items.menu.addToCollection=Add to Collection
|
||||||
|
|
@ -343,6 +348,8 @@ pane.items.menu.export=Export Selected Item...
|
||||||
pane.items.menu.export.multiple=Export Selected Items...
|
pane.items.menu.export.multiple=Export Selected Items...
|
||||||
pane.items.menu.exportNote=Export Note…
|
pane.items.menu.exportNote=Export Note…
|
||||||
pane.items.menu.exportNote.multiple=Export Notes…
|
pane.items.menu.exportNote.multiple=Export Notes…
|
||||||
|
pane.items.menu.exportPDF=Export PDF…
|
||||||
|
pane.items.menu.exportPDF.multiple=Export PDFs…
|
||||||
pane.items.menu.createBib=Create Bibliography from Selected Item...
|
pane.items.menu.createBib=Create Bibliography from Selected Item...
|
||||||
pane.items.menu.createBib.multiple=Create Bibliography from Selected Items...
|
pane.items.menu.createBib.multiple=Create Bibliography from Selected Items...
|
||||||
pane.items.menu.generateReport=Generate Report from Selected Item...
|
pane.items.menu.generateReport=Generate Report from Selected Item...
|
||||||
|
|
@ -355,6 +362,8 @@ pane.items.menu.createParent=Create Parent Item…
|
||||||
pane.items.menu.createParent.multiple=Create Parent Items
|
pane.items.menu.createParent.multiple=Create Parent Items
|
||||||
pane.items.menu.renameAttachments=Rename File from Parent Metadata
|
pane.items.menu.renameAttachments=Rename File from Parent Metadata
|
||||||
pane.items.menu.renameAttachments.multiple=Rename Files from Parent Metadata
|
pane.items.menu.renameAttachments.multiple=Rename Files from Parent Metadata
|
||||||
|
pane.items.menu.duplicateAndConvert.toBookSection=Create Book Section
|
||||||
|
pane.items.menu.duplicateAndConvert.toBook=Create Book from Book Section
|
||||||
pane.items.showItemInLibrary=Show Item in Library
|
pane.items.showItemInLibrary=Show Item in Library
|
||||||
|
|
||||||
pane.items.letter.oneParticipant=Letter to %S
|
pane.items.letter.oneParticipant=Letter to %S
|
||||||
|
|
@ -408,6 +417,16 @@ pane.item.attachments.fileNotFound.text2.stored=It may have been moved or delete
|
||||||
pane.item.attachments.fileNotFound.text2.stored.notOnServer=It may have been moved or deleted outside of %1$S, or, if the file was added on another computer, it may not yet have been synced to %2$S.
|
pane.item.attachments.fileNotFound.text2.stored.notOnServer=It may have been moved or deleted outside of %1$S, or, if the file was added on another computer, it may not yet have been synced to %2$S.
|
||||||
pane.item.attachments.fileNotFound.text2.linked=It may have been moved or deleted outside of %1$S, or a Linked Attachment Base Directory may be set incorrectly on one of your computers.
|
pane.item.attachments.fileNotFound.text2.linked=It may have been moved or deleted outside of %1$S, or a Linked Attachment Base Directory may be set incorrectly on one of your computers.
|
||||||
pane.item.attachments.delete.confirm=Are you sure you want to delete this attachment?
|
pane.item.attachments.delete.confirm=Are you sure you want to delete this attachment?
|
||||||
|
pane.item.attachments.autoRelink.title=File Located Automatically
|
||||||
|
pane.item.attachments.autoRelink.text1=The file could not be found at the specified location, but a file with the same name was found within your Linked Attachment Base Directory:
|
||||||
|
pane.item.attachments.autoRelink.text2=Old Location: %S
|
||||||
|
pane.item.attachments.autoRelink.text3=New Location: %S
|
||||||
|
pane.item.attachments.autoRelink.text4=%1$S can automatically relink this attachment.
|
||||||
|
pane.item.attachments.autoRelink.relink=Relink
|
||||||
|
pane.item.attachments.autoRelinkOthers.title=Additional Files Located
|
||||||
|
pane.item.attachments.autoRelinkOthers.text=One other unlinked attachment in this library was found within the same directory. Relink this attachment as well?;%S other unlinked attachments in this library were found within the same directory. Relink all located attachments?
|
||||||
|
pane.item.attachments.autoRelink.locateManually=Locate Manually…
|
||||||
|
pane.item.attachments.autoRelink.relinkAll=Relink All
|
||||||
pane.item.attachments.count.zero=%S attachments:
|
pane.item.attachments.count.zero=%S attachments:
|
||||||
pane.item.attachments.count.singular=%S attachment:
|
pane.item.attachments.count.singular=%S attachment:
|
||||||
pane.item.attachments.count.plural=%S attachments:
|
pane.item.attachments.count.plural=%S attachments:
|
||||||
|
|
@ -478,34 +497,34 @@ itemTypes.preprint=Preprint
|
||||||
|
|
||||||
itemFields.itemType=Type
|
itemFields.itemType=Type
|
||||||
itemFields.title=Title
|
itemFields.title=Title
|
||||||
itemFields.dateAdded=Date Added
|
itemFields.dateAdded=Datum bygevoeg
|
||||||
itemFields.dateModified=Modified
|
itemFields.dateModified=Modified
|
||||||
itemFields.source=Source
|
itemFields.source=Source
|
||||||
itemFields.notes=Notes
|
itemFields.notes=Notas
|
||||||
itemFields.tags=Tags
|
itemFields.tags=Etikette
|
||||||
itemFields.attachments=Attachments
|
itemFields.attachments=Aanhegsels
|
||||||
itemFields.related=Related
|
itemFields.related=Verwant
|
||||||
itemFields.url=URL
|
itemFields.url=URL
|
||||||
itemFields.rights=Rights
|
itemFields.rights=Regte
|
||||||
itemFields.series=Series
|
itemFields.series=Series
|
||||||
itemFields.volume=Volume
|
itemFields.volume=Volume
|
||||||
itemFields.issue=Issue
|
itemFields.issue=Issue
|
||||||
itemFields.edition=Edition
|
itemFields.edition=Edition
|
||||||
itemFields.place=Place
|
itemFields.place=Place
|
||||||
itemFields.publisher=Publisher
|
itemFields.publisher=Uitgewer
|
||||||
itemFields.pages=Pages
|
itemFields.pages=Pages
|
||||||
itemFields.ISBN=ISBN
|
itemFields.ISBN=ISBN
|
||||||
itemFields.publicationTitle=Publication
|
itemFields.publicationTitle=Publikasie
|
||||||
itemFields.ISSN=ISSN
|
itemFields.ISSN=ISSN
|
||||||
itemFields.date=Date
|
itemFields.date=Datum
|
||||||
itemFields.section=Section
|
itemFields.section=Section
|
||||||
itemFields.callNumber=Call Number
|
itemFields.callNumber=Telefoonnommer
|
||||||
itemFields.archiveLocation=Loc. in Archive
|
itemFields.archiveLocation=Loc. in Archive
|
||||||
itemFields.distributor=Distributor
|
itemFields.distributor=Distributor
|
||||||
itemFields.extra=Extra
|
itemFields.extra=Extra
|
||||||
itemFields.journalAbbreviation=Journal Abbr
|
itemFields.journalAbbreviation=Joernaalafkorting
|
||||||
itemFields.DOI=DOI
|
itemFields.DOI=DOI
|
||||||
itemFields.accessDate=Accessed
|
itemFields.accessDate=Gebruik/Toegang verkry
|
||||||
itemFields.seriesTitle=Series Title
|
itemFields.seriesTitle=Series Title
|
||||||
itemFields.seriesText=Series Text
|
itemFields.seriesText=Series Text
|
||||||
itemFields.seriesNumber=Series Number
|
itemFields.seriesNumber=Series Number
|
||||||
|
|
@ -529,7 +548,7 @@ itemFields.codeNumber=Code Number
|
||||||
itemFields.artworkMedium=Medium
|
itemFields.artworkMedium=Medium
|
||||||
itemFields.number=Number
|
itemFields.number=Number
|
||||||
itemFields.artworkSize=Artwork Size
|
itemFields.artworkSize=Artwork Size
|
||||||
itemFields.libraryCatalog=Library Catalog
|
itemFields.libraryCatalog=Biblioteekkatalogus
|
||||||
itemFields.videoRecordingFormat=Format
|
itemFields.videoRecordingFormat=Format
|
||||||
itemFields.interviewMedium=Medium
|
itemFields.interviewMedium=Medium
|
||||||
itemFields.letterType=Type
|
itemFields.letterType=Type
|
||||||
|
|
@ -719,6 +738,7 @@ zotero.preferences.export.quickCopy.citationStyles=Citation Styles
|
||||||
zotero.preferences.export.quickCopy.exportFormats=Export Formats
|
zotero.preferences.export.quickCopy.exportFormats=Export Formats
|
||||||
zotero.preferences.export.quickCopy.instructions=Quick Copy allows you to quickly export items in a given format. You can copy selected items to the clipboard by pressing %S or drag items directly into a text box in another program.
|
zotero.preferences.export.quickCopy.instructions=Quick Copy allows you to quickly export items in a given format. You can copy selected items to the clipboard by pressing %S or drag items directly into a text box in another program.
|
||||||
zotero.preferences.export.quickCopy.citationInstructions=For citation styles, you can copy citations or footnotes by pressing %S or holding down Shift before dragging items.
|
zotero.preferences.export.quickCopy.citationInstructions=For citation styles, you can copy citations or footnotes by pressing %S or holding down Shift before dragging items.
|
||||||
|
zotero.preferences.export.quickCopy.note.htmlOptions.label=Rich Text/HTML
|
||||||
|
|
||||||
zotero.preferences.wordProcessors.installationSuccess=Installation was successful.
|
zotero.preferences.wordProcessors.installationSuccess=Installation was successful.
|
||||||
zotero.preferences.wordProcessors.installationError=Installation could not be completed because an error occurred. Please ensure that %1$S is closed, and then restart %2$S.
|
zotero.preferences.wordProcessors.installationError=Installation could not be completed because an error occurred. Please ensure that %1$S is closed, and then restart %2$S.
|
||||||
|
|
@ -812,11 +832,11 @@ searchOperator.isInTheLast=is in the last
|
||||||
searchConditions.tooltip.fields=Fields:
|
searchConditions.tooltip.fields=Fields:
|
||||||
searchConditions.collection=Collection
|
searchConditions.collection=Collection
|
||||||
searchConditions.savedSearch=Saved Search
|
searchConditions.savedSearch=Saved Search
|
||||||
searchConditions.itemTypeID=Item Type
|
searchConditions.itemTypeID=Tipe item
|
||||||
searchConditions.tag=Tag
|
searchConditions.tag=Tag
|
||||||
searchConditions.note=Note
|
searchConditions.note=Note
|
||||||
searchConditions.childNote=Child Note
|
searchConditions.childNote=Child Note
|
||||||
searchConditions.creator=Creator
|
searchConditions.creator=Skepper
|
||||||
searchConditions.type=Type
|
searchConditions.type=Type
|
||||||
searchConditions.thesisType=Thesis Type
|
searchConditions.thesisType=Thesis Type
|
||||||
searchConditions.reportType=Report Type
|
searchConditions.reportType=Report Type
|
||||||
|
|
@ -830,7 +850,7 @@ searchConditions.presentationType=Presentation Type
|
||||||
searchConditions.mapType=Map Type
|
searchConditions.mapType=Map Type
|
||||||
searchConditions.medium=Medium
|
searchConditions.medium=Medium
|
||||||
searchConditions.artworkMedium=Artwork Medium
|
searchConditions.artworkMedium=Artwork Medium
|
||||||
searchConditions.dateModified=Date Modified
|
searchConditions.dateModified=Datum gewysig
|
||||||
searchConditions.fulltextContent=Attachment Content
|
searchConditions.fulltextContent=Attachment Content
|
||||||
searchConditions.programmingLanguage=Programming Language
|
searchConditions.programmingLanguage=Programming Language
|
||||||
searchConditions.fileTypeID=Attachment File Type
|
searchConditions.fileTypeID=Attachment File Type
|
||||||
|
|
@ -863,23 +883,8 @@ citation.singleSource=Single Source...
|
||||||
citation.showEditor=Show Editor...
|
citation.showEditor=Show Editor...
|
||||||
citation.hideEditor=Hide Editor...
|
citation.hideEditor=Hide Editor...
|
||||||
citation.citations=Citations
|
citation.citations=Citations
|
||||||
citation.notes=Notes
|
citation.notes=Notas
|
||||||
citation.locator.page=Page
|
citation.locator.timestamp=Timestamp
|
||||||
citation.locator.book=Book
|
|
||||||
citation.locator.chapter=Chapter
|
|
||||||
citation.locator.column=Column
|
|
||||||
citation.locator.figure=Figure
|
|
||||||
citation.locator.folio=Folio
|
|
||||||
citation.locator.issue=Issue
|
|
||||||
citation.locator.line=Line
|
|
||||||
citation.locator.note=Note
|
|
||||||
citation.locator.opus=Opus
|
|
||||||
citation.locator.paragraph=Paragraph
|
|
||||||
citation.locator.part=Part
|
|
||||||
citation.locator.section=Section
|
|
||||||
citation.locator.subverbo=Sub verbo
|
|
||||||
citation.locator.volume=Volume
|
|
||||||
citation.locator.verse=Verse
|
|
||||||
|
|
||||||
report.title.default=Zotero Report
|
report.title.default=Zotero Report
|
||||||
report.parentItem=Parent Item:
|
report.parentItem=Parent Item:
|
||||||
|
|
@ -940,7 +945,7 @@ integration.error.misconfiguredWordStartupFolder.some=%S could not install the W
|
||||||
integration.error.misconfiguredWordStartupFolder.all=%S could not install the Word plugin because the Word Startup folder location is misconfigured.
|
integration.error.misconfiguredWordStartupFolder.all=%S could not install the Word plugin because the Word Startup folder location is misconfigured.
|
||||||
integration.error.misconfiguredWordStartupFolder.fix=The plugin may not appear in Word until you reset your Startup folder to the default location.
|
integration.error.misconfiguredWordStartupFolder.fix=The plugin may not appear in Word until you reset your Startup folder to the default location.
|
||||||
integration.error.macWordSBPermissionsMissing.title=Missing Permission
|
integration.error.macWordSBPermissionsMissing.title=Missing Permission
|
||||||
integration.error.macWordSBPermissionsMissing=Zotero does not have permission to control Word. To grant this permission:\n\n1) Open System Preferences\n2) Click on “Security & Privacy”\n3) Select the “Privacy” tab\n4) Find and select “Automation” on the left\n5) Check the checkbox for “Microsoft Word” under “Zotero”\n6) Restart Word
|
integration.error.macWordSBPermissionsMissing=Zotero does not have permission to control Word. To grant this permission:\n\n1) Open System Settings\n2) Select “Privacy & Security” in the left column\n3) Select “Automation”\n4) Find “Zotero” and click the arrow to expand it\n5) Make sure “Microsoft Word” is enabled under “Zotero”\n6) Restart Word
|
||||||
integration.error.macWordSBPermissionsMissing.pre2016=If “Microsoft Word” does not appear under “Automation”, make sure you are running Word 2011 version 14.7.7 or later.
|
integration.error.macWordSBPermissionsMissing.pre2016=If “Microsoft Word” does not appear under “Automation”, make sure you are running Word 2011 version 14.7.7 or later.
|
||||||
integration.error.m1UpgradeOS.title=macOS Upgrade Required
|
integration.error.m1UpgradeOS.title=macOS Upgrade Required
|
||||||
integration.error.m1UpgradeOS=Citing in Word on an Apple Silicon Mac with macOS 11.3 or earlier is not supported and may cause %S to freeze. Please upgrade to macOS 11.4 or later.
|
integration.error.m1UpgradeOS=Citing in Word on an Apple Silicon Mac with macOS 11.3 or earlier is not supported and may cause %S to freeze. Please upgrade to macOS 11.4 or later.
|
||||||
|
|
@ -1098,8 +1103,8 @@ sync.storage.mbRemaining=%SMB remaining
|
||||||
sync.storage.kbRemaining=%SKB remaining
|
sync.storage.kbRemaining=%SKB remaining
|
||||||
sync.storage.filesRemaining=%1$S/%2$S files
|
sync.storage.filesRemaining=%1$S/%2$S files
|
||||||
sync.storage.none=None
|
sync.storage.none=None
|
||||||
sync.storage.downloads=Downloads:
|
sync.storage.downloads=Aflaaie:
|
||||||
sync.storage.uploads=Uploads:
|
sync.storage.uploads=Oplaaie:
|
||||||
sync.storage.localFile=Local File
|
sync.storage.localFile=Local File
|
||||||
sync.storage.remoteFile=Remote File
|
sync.storage.remoteFile=Remote File
|
||||||
sync.storage.savedFile=Saved File
|
sync.storage.savedFile=Saved File
|
||||||
|
|
@ -1218,6 +1223,8 @@ locate.externalViewer.label=Open in External Viewer
|
||||||
locate.internalViewer.label=Open in Internal Viewer
|
locate.internalViewer.label=Open in Internal Viewer
|
||||||
locate.showFile.label=Show File
|
locate.showFile.label=Show File
|
||||||
locate.libraryLookup.label=Library Lookup
|
locate.libraryLookup.label=Library Lookup
|
||||||
|
locate.libraryLookup.noResolver.title=No OpenURL Resolver
|
||||||
|
locate.libraryLookup.noResolver.text=You must choose an OpenURL resolver from the Advanced pane of the %S preferences.
|
||||||
locate.manageLocateEngines=Manage Lookup Engines...
|
locate.manageLocateEngines=Manage Lookup Engines...
|
||||||
locate.locateEngineDescription=Lookup engines help you find resources in your %S library on the web. Engines enabled in this list appear in the Locate drop-down in the toolbar.
|
locate.locateEngineDescription=Lookup engines help you find resources in your %S library on the web. Engines enabled in this list appear in the Locate drop-down in the toolbar.
|
||||||
|
|
||||||
|
|
@ -1303,20 +1310,21 @@ noteEditor.enterLink=Enter Link
|
||||||
noteEditor.heading1=Heading 1
|
noteEditor.heading1=Heading 1
|
||||||
noteEditor.heading2=Heading 2
|
noteEditor.heading2=Heading 2
|
||||||
noteEditor.heading3=Heading 3
|
noteEditor.heading3=Heading 3
|
||||||
noteEditor.paragraph=Paragraph
|
noteEditor.paragraph=Paragraaf
|
||||||
noteEditor.monospaced=Monospaced
|
noteEditor.monospaced=Monospaced
|
||||||
noteEditor.bulletList=Bulleted List
|
noteEditor.bulletList=Bulleted List
|
||||||
noteEditor.orderedList=Numbered List
|
noteEditor.orderedList=Numbered List
|
||||||
noteEditor.blockquote=Block Quote
|
noteEditor.blockquote=Block Quote
|
||||||
|
noteEditor.mathBlock=Math Block
|
||||||
noteEditor.formatText=Format Text
|
noteEditor.formatText=Format Text
|
||||||
noteEditor.highlightText=Highlight Text
|
noteEditor.highlightText=Verligmerk teks
|
||||||
noteEditor.removeColor=Remove Color
|
noteEditor.removeColor=Remove Color
|
||||||
noteEditor.bold=Bold
|
noteEditor.bold=Vetdruk
|
||||||
noteEditor.italic=Italic
|
noteEditor.italic=Kursief
|
||||||
noteEditor.underline=Underline
|
noteEditor.underline=Onderstreep
|
||||||
noteEditor.strikethrough=Strikethrough
|
noteEditor.strikethrough=Strikethrough
|
||||||
noteEditor.subscript=Subscript
|
noteEditor.subscript=Onderskrif
|
||||||
noteEditor.superscript=Superscript
|
noteEditor.superscript=Boskrif
|
||||||
noteEditor.returnToNotesList=Return to Notes List
|
noteEditor.returnToNotesList=Return to Notes List
|
||||||
noteEditor.insertLink=Insert Link
|
noteEditor.insertLink=Insert Link
|
||||||
noteEditor.clearFormatting=Clear Formatting
|
noteEditor.clearFormatting=Clear Formatting
|
||||||
|
|
@ -1338,7 +1346,7 @@ noteEditor.editCitation=Edit Citation
|
||||||
noteEditor.showOnPage=Show on Page
|
noteEditor.showOnPage=Show on Page
|
||||||
noteEditor.unlink=Unlink
|
noteEditor.unlink=Unlink
|
||||||
noteEditor.set=Set
|
noteEditor.set=Set
|
||||||
noteEditor.edit=Edit
|
noteEditor.edit=Redigeer
|
||||||
noteEditor.addCitation=Add Citation
|
noteEditor.addCitation=Add Citation
|
||||||
noteEditor.removeCitation=Hide Citation
|
noteEditor.removeCitation=Hide Citation
|
||||||
noteEditor.findAndReplace=Find and Replace
|
noteEditor.findAndReplace=Find and Replace
|
||||||
|
|
@ -1347,7 +1355,11 @@ noteEditor.applyAnnotationColors=Show Annotation Colors
|
||||||
noteEditor.removeAnnotationColors=Hide Annotation Colors
|
noteEditor.removeAnnotationColors=Hide Annotation Colors
|
||||||
noteEditor.addCitations=Show Annotation Citations
|
noteEditor.addCitations=Show Annotation Citations
|
||||||
noteEditor.removeCitations=Hide Annotation Citations
|
noteEditor.removeCitations=Hide Annotation Citations
|
||||||
noteEditor.insertTable=Insert Table
|
noteEditor.image=Image
|
||||||
|
noteEditor.math=Math
|
||||||
|
noteEditor.table=Table
|
||||||
|
noteEditor.copyImage=Copy Image
|
||||||
|
noteEditor.saveImageAs=Save Image As…
|
||||||
noteEditor.insertRowBefore=Insert Row Above
|
noteEditor.insertRowBefore=Insert Row Above
|
||||||
noteEditor.insertRowAfter=Insert Row Below
|
noteEditor.insertRowAfter=Insert Row Below
|
||||||
noteEditor.insertColumnBefore=Insert Column Left
|
noteEditor.insertColumnBefore=Insert Column Left
|
||||||
|
|
@ -1360,10 +1372,10 @@ pdfReader.annotations=Annotations
|
||||||
pdfReader.showAnnotations=Show Annotations
|
pdfReader.showAnnotations=Show Annotations
|
||||||
pdfReader.searchAnnotations=Search Annotations
|
pdfReader.searchAnnotations=Search Annotations
|
||||||
pdfReader.noAnnotations=Create an annotation to see it in the sidebar
|
pdfReader.noAnnotations=Create an annotation to see it in the sidebar
|
||||||
pdfReader.addText=Add extracted text
|
pdfReader.noExtractedText=No extracted text
|
||||||
pdfReader.addComment=Add comment
|
pdfReader.addComment=Add comment
|
||||||
pdfReader.addTags=Add tags…
|
pdfReader.addTags=Add tags…
|
||||||
pdfReader.highlightText=Highlight Text
|
pdfReader.highlightText=Verligmerk teks
|
||||||
pdfReader.addNote=Add Note
|
pdfReader.addNote=Add Note
|
||||||
pdfReader.selectArea=Select Area
|
pdfReader.selectArea=Select Area
|
||||||
pdfReader.pickColor=Pick a Color
|
pdfReader.pickColor=Pick a Color
|
||||||
|
|
@ -1373,17 +1385,26 @@ pdfReader.zoomOut=Zoom Out
|
||||||
pdfReader.zoomAuto=Automatically Resize
|
pdfReader.zoomAuto=Automatically Resize
|
||||||
pdfReader.zoomPageWidth=Zoom to Page Width
|
pdfReader.zoomPageWidth=Zoom to Page Width
|
||||||
pdfReader.zoomPageHeight=Zoom to Page Height
|
pdfReader.zoomPageHeight=Zoom to Page Height
|
||||||
|
pdfReader.splitVertically=Split Vertically
|
||||||
|
pdfReader.splitHorizontally=Split Horizontally
|
||||||
pdfReader.nextPage=Next Page
|
pdfReader.nextPage=Next Page
|
||||||
pdfReader.previousPage=Previous Page
|
pdfReader.previousPage=Previous Page
|
||||||
pdfReader.page=Page
|
pdfReader.page=Bladsy
|
||||||
pdfReader.readOnly=Read-only
|
pdfReader.readOnly=Read-only
|
||||||
pdfReader.promptTransferFromPDF.title=Import Annotations
|
pdfReader.promptTransferFromPDF.title=Import Annotations
|
||||||
pdfReader.promptTransferFromPDF.text=Annotations stored in the PDF file will be moved to %1$S.
|
pdfReader.promptTransferFromPDF.text=Annotations stored in the PDF file will be moved to %1$S.
|
||||||
pdfReader.promptTransferToPDF.title=Store Annotations in File
|
pdfReader.promptTransferToPDF.title=Store Annotations in File
|
||||||
pdfReader.promptTransferToPDF.text=Annotations will be transferred to the PDF file and will no longer be editable in %S.
|
pdfReader.promptTransferToPDF.text=Annotations will be transferred to the PDF file and will no longer be editable in %S.
|
||||||
pdfReader.promptPasswordProtected=The operation is not supported for password-protected PDF files.
|
pdfReader.promptPasswordProtected=The operation is not supported for password-protected PDF files.
|
||||||
|
pdfReader.promptDeletePages.title=Delete Pages
|
||||||
|
pdfReader.promptDeletePages.text=Are you sure you want to delete %1$S page from the PDF file?;Are you sure you want to delete %1$S pages from the PDF file?
|
||||||
|
pdfReader.rotateLeft=Rotate Left
|
||||||
|
pdfReader.rotateRight=Rotate Right
|
||||||
|
pdfReader.rotate180=Rotate 180°
|
||||||
pdfReader.editPageNumber=Edit Page Number…
|
pdfReader.editPageNumber=Edit Page Number…
|
||||||
pdfReader.editHighlightedText=Edit Highlighted Text
|
pdfReader.editHighlightedText=Edit Highlighted Text
|
||||||
|
pdfReader.copyImage=Copy Image
|
||||||
|
pdfReader.saveImageAs=Save Image As…
|
||||||
pdfReader.pageNumberPopupHeader=Change page number for:
|
pdfReader.pageNumberPopupHeader=Change page number for:
|
||||||
pdfReader.thisAnnotation=This annotation
|
pdfReader.thisAnnotation=This annotation
|
||||||
pdfReader.selectedAnnotations=Selected annotations
|
pdfReader.selectedAnnotations=Selected annotations
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,12 @@
|
||||||
"general_done": {
|
"general_done": {
|
||||||
"message": "تم"
|
"message": "تم"
|
||||||
},
|
},
|
||||||
|
"general_yes": {
|
||||||
|
"message": "نعم"
|
||||||
|
},
|
||||||
|
"general_no": {
|
||||||
|
"message": "لا"
|
||||||
|
},
|
||||||
"general_tryAgain": {
|
"general_tryAgain": {
|
||||||
"message": "حاول مرة أخرى"
|
"message": "حاول مرة أخرى"
|
||||||
},
|
},
|
||||||
|
|
@ -14,6 +20,9 @@
|
||||||
"general_cancel": {
|
"general_cancel": {
|
||||||
"message": "إلغاء"
|
"message": "إلغاء"
|
||||||
},
|
},
|
||||||
|
"general_copyToClipboard": {
|
||||||
|
"message": "انسخ إلى الحافظة"
|
||||||
|
},
|
||||||
"progressWindow_savingTo": {
|
"progressWindow_savingTo": {
|
||||||
"message": "الحفظ في"
|
"message": "الحفظ في"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<!ENTITY zotero.general.deselectAll "إلغاء تحديد الكل">
|
<!ENTITY zotero.general.deselectAll "إلغاء تحديد الكل">
|
||||||
<!ENTITY zotero.general.edit "تحرير">
|
<!ENTITY zotero.general.edit "تحرير">
|
||||||
<!ENTITY zotero.general.delete "حذف">
|
<!ENTITY zotero.general.delete "حذف">
|
||||||
<!ENTITY zotero.general.moveToTrash "Move to Trash">
|
<!ENTITY zotero.general.moveToTrash "نقل لسلة المحذوفات">
|
||||||
<!ENTITY zotero.general.ok "موافق">
|
<!ENTITY zotero.general.ok "موافق">
|
||||||
<!ENTITY zotero.general.cancel "الغاء">
|
<!ENTITY zotero.general.cancel "الغاء">
|
||||||
<!ENTITY zotero.general.refresh "اعادة تحميل">
|
<!ENTITY zotero.general.refresh "اعادة تحميل">
|
||||||
|
|
@ -307,12 +307,10 @@
|
||||||
<!ENTITY zotero.context.addStandaloneNoteFromAnnotations "Add Standalone Note from Annotations">
|
<!ENTITY zotero.context.addStandaloneNoteFromAnnotations "Add Standalone Note from Annotations">
|
||||||
<!ENTITY zotero.context.editInWindow "Edit in a Separate Window">
|
<!ENTITY zotero.context.editInWindow "Edit in a Separate Window">
|
||||||
|
|
||||||
<!ENTITY zotero.pdfReader.firstPage "First Page">
|
<!ENTITY zotero.pdfReader.firstPage "الصفحة الأولى">
|
||||||
<!ENTITY zotero.pdfReader.lastPage "Last Page">
|
<!ENTITY zotero.pdfReader.lastPage "Last Page">
|
||||||
<!ENTITY zotero.pdfReader.back "Back">
|
<!ENTITY zotero.pdfReader.back "Back">
|
||||||
<!ENTITY zotero.pdfReader.forward "Forward">
|
<!ENTITY zotero.pdfReader.forward "Forward">
|
||||||
<!ENTITY zotero.pdfReader.rotateClockwise "Rotate Clockwise">
|
|
||||||
<!ENTITY zotero.pdfReader.rotateCounterclockwise "Rotate Counterclockwise">
|
|
||||||
<!ENTITY zotero.pdfReader.handTool "Hand Tool">
|
<!ENTITY zotero.pdfReader.handTool "Hand Tool">
|
||||||
<!ENTITY zotero.pdfReader.verticalScrolling "Vertical Scrolling">
|
<!ENTITY zotero.pdfReader.verticalScrolling "Vertical Scrolling">
|
||||||
<!ENTITY zotero.pdfReader.horizontalScrolling "Horizontal Scrolling">
|
<!ENTITY zotero.pdfReader.horizontalScrolling "Horizontal Scrolling">
|
||||||
|
|
@ -325,4 +323,9 @@
|
||||||
<!ENTITY zotero.pdfReader.zoomAuto "Automatically Resize">
|
<!ENTITY zotero.pdfReader.zoomAuto "Automatically Resize">
|
||||||
<!ENTITY zotero.pdfReader.zoomPageWidth "Zoom to Page Width">
|
<!ENTITY zotero.pdfReader.zoomPageWidth "Zoom to Page Width">
|
||||||
<!ENTITY zotero.pdfReader.zoomPageHeight "Zoom to Page Height">
|
<!ENTITY zotero.pdfReader.zoomPageHeight "Zoom to Page Height">
|
||||||
|
<!ENTITY zotero.pdfReader.splitVertically "Split Vertically">
|
||||||
|
<!ENTITY zotero.pdfReader.splitHorizontally "Split Horizontally">
|
||||||
<!ENTITY zotero.pdfReader.transferFromPDF "Import Annotations…">
|
<!ENTITY zotero.pdfReader.transferFromPDF "Import Annotations…">
|
||||||
|
<!ENTITY zotero.pdfReader.rotatePageLeft "Rotate Page Left">
|
||||||
|
<!ENTITY zotero.pdfReader.rotatePageRight "Rotate Page Right">
|
||||||
|
<!ENTITY zotero.pdfReader.rotatePage180 "Rotate Page 180°">
|
||||||
|
|
|
||||||
|
|
@ -89,9 +89,10 @@ general.back=Back
|
||||||
general.languages=Languages
|
general.languages=Languages
|
||||||
general.default=Default
|
general.default=Default
|
||||||
general.custom=Custom
|
general.custom=Custom
|
||||||
general.loading=Loading…
|
general.loading=التحميل
|
||||||
general.richText=Rich Text
|
general.richText=Rich Text
|
||||||
general.clearSelection=Clear Selection
|
general.clearSelection=Clear Selection
|
||||||
|
general.insert=Insert
|
||||||
|
|
||||||
general.yellow=Yellow
|
general.yellow=Yellow
|
||||||
general.red=Red
|
general.red=Red
|
||||||
|
|
@ -114,6 +115,7 @@ about.getInvolved=هل تريد المساعدة ؟ [شارك] اليوم!
|
||||||
punctuation.openingQMark=“
|
punctuation.openingQMark=“
|
||||||
punctuation.closingQMark=”
|
punctuation.closingQMark=”
|
||||||
punctuation.colon=:
|
punctuation.colon=:
|
||||||
|
punctuation.colon.withString=%S:
|
||||||
punctuation.ellipsis=…
|
punctuation.ellipsis=…
|
||||||
|
|
||||||
install.quickStartGuide=دليل الاستخدام المبسط لزوتيرو
|
install.quickStartGuide=دليل الاستخدام المبسط لزوتيرو
|
||||||
|
|
@ -183,7 +185,7 @@ dataDir.unsafeLocation.existing.cloud=Your %S data directory appears to be withi
|
||||||
dataDir.unsafeLocation.existing.chooseDifferent=Would you like to choose a different location now?
|
dataDir.unsafeLocation.existing.chooseDifferent=Would you like to choose a different location now?
|
||||||
dataDir.selectedDirNonEmpty.title=المجلد غير فارغ
|
dataDir.selectedDirNonEmpty.title=المجلد غير فارغ
|
||||||
dataDir.selectedDirNonEmpty.text=المجلد المحدد غير فارغ، ولا يبدو انه مجلد بيانات زوتيرو.\n\nهل ترغب بإنشاء ملفات زوتيرو في هذا الدليل؟
|
dataDir.selectedDirNonEmpty.text=المجلد المحدد غير فارغ، ولا يبدو انه مجلد بيانات زوتيرو.\n\nهل ترغب بإنشاء ملفات زوتيرو في هذا الدليل؟
|
||||||
dataDir.mustSelectEmpty.title=Directory Not Empty
|
dataDir.mustSelectEmpty.title=المجلد غير فارغ
|
||||||
dataDir.mustSelectEmpty.text=The directory you selected is not empty. You must select an empty directory to continue.
|
dataDir.mustSelectEmpty.text=The directory you selected is not empty. You must select an empty directory to continue.
|
||||||
dataDir.selectedDirEmpty.title=مجلد فارغ
|
dataDir.selectedDirEmpty.title=مجلد فارغ
|
||||||
dataDir.selectedDirEmpty.text=الدليل الذي حددته فارغ. لنقل دليل بيانات زوتيرو موجود ، ستحتاج إلى نقل الملفات يدوياً من دليل البيانات الموجود إلى الموقع الجديد بعد إغلاق %1$S.
|
dataDir.selectedDirEmpty.text=الدليل الذي حددته فارغ. لنقل دليل بيانات زوتيرو موجود ، ستحتاج إلى نقل الملفات يدوياً من دليل البيانات الموجود إلى الموقع الجديد بعد إغلاق %1$S.
|
||||||
|
|
@ -255,10 +257,10 @@ pane.collections.savedSearchName=أدخل اسماً لهذا البحث الم
|
||||||
pane.collections.rename=إعادة تسمية مجموعة العناصر:
|
pane.collections.rename=إعادة تسمية مجموعة العناصر:
|
||||||
pane.collections.library=مكتبتي
|
pane.collections.library=مكتبتي
|
||||||
pane.collections.publications=منشوراتي
|
pane.collections.publications=منشوراتي
|
||||||
pane.collections.feeds=Feeds
|
pane.collections.feeds=الملقمات
|
||||||
pane.collections.libraryAndFeeds=My Library & Feeds
|
pane.collections.libraryAndFeeds=My Library & Feeds
|
||||||
pane.collections.groupLibraries=مكتبات المجموعات
|
pane.collections.groupLibraries=مكتبات المجموعات
|
||||||
pane.collections.feedLibraries=Feeds
|
pane.collections.feedLibraries=الملقمات
|
||||||
pane.collections.trash=سلة المحذوفات
|
pane.collections.trash=سلة المحذوفات
|
||||||
pane.collections.untitled=بدون عنوان
|
pane.collections.untitled=بدون عنوان
|
||||||
pane.collections.unfiled=العناصر الغير مصنفة
|
pane.collections.unfiled=العناصر الغير مصنفة
|
||||||
|
|
@ -270,7 +272,7 @@ pane.collections.removeLibrary.text=Are you sure you want to permanently remove
|
||||||
pane.collections.menu.rename.collection=إعادة تسمية مجموعة العناصر...
|
pane.collections.menu.rename.collection=إعادة تسمية مجموعة العناصر...
|
||||||
pane.collections.menu.duplicate.savedSearch=تكرار البحث المحفوظ
|
pane.collections.menu.duplicate.savedSearch=تكرار البحث المحفوظ
|
||||||
pane.collections.menu.edit.savedSearch=تحرير البحث المحفوظ
|
pane.collections.menu.edit.savedSearch=تحرير البحث المحفوظ
|
||||||
pane.collections.menu.edit.feed=Edit Feed…
|
pane.collections.menu.edit.feed=تحرير الخلاصة...
|
||||||
pane.collections.menu.remove.library=إزالة المكتبة...
|
pane.collections.menu.remove.library=إزالة المكتبة...
|
||||||
pane.collections.menu.delete.collection=امسح مجموعة العناصر...
|
pane.collections.menu.delete.collection=امسح مجموعة العناصر...
|
||||||
pane.collections.menu.delete.collectionAndItems=Delete Collection and Items…
|
pane.collections.menu.delete.collectionAndItems=Delete Collection and Items…
|
||||||
|
|
@ -288,7 +290,7 @@ pane.collections.menu.generateReport.collection=انتاج تقرير من مج
|
||||||
pane.collections.menu.generateReport.savedSearch=انتاج تقرير من البحث المخزن...
|
pane.collections.menu.generateReport.savedSearch=انتاج تقرير من البحث المخزن...
|
||||||
pane.collections.menu.generateReport.feed=Generate Report from Feed…
|
pane.collections.menu.generateReport.feed=Generate Report from Feed…
|
||||||
|
|
||||||
pane.collections.menu.refresh.feed=Refresh Feed
|
pane.collections.menu.refresh.feed=تحديث الخلاصة
|
||||||
|
|
||||||
pane.tagSelector.rename.title=إعادة تسمية الوسم
|
pane.tagSelector.rename.title=إعادة تسمية الوسم
|
||||||
pane.tagSelector.rename.message=من فضلك ادخل إسماً لهذا الوسم الجديد.\n\nسيتم إعادة تسمية الوسم في جميع العناصر المرتبطة.
|
pane.tagSelector.rename.message=من فضلك ادخل إسماً لهذا الوسم الجديد.\n\nسيتم إعادة تسمية الوسم في جميع العناصر المرتبطة.
|
||||||
|
|
@ -327,8 +329,11 @@ pane.items.remove.multiple=Are you sure you want to remove the selected items fr
|
||||||
pane.items.removeFromPublications.title=أزل من منشوراتي
|
pane.items.removeFromPublications.title=أزل من منشوراتي
|
||||||
pane.items.removeFromPublications=Are you sure you want to remove the selected item from My Publications?
|
pane.items.removeFromPublications=Are you sure you want to remove the selected item from My Publications?
|
||||||
pane.items.removeFromPublications.multiple=Are you sure you want to remove the selected items from My Publications?
|
pane.items.removeFromPublications.multiple=Are you sure you want to remove the selected items from My Publications?
|
||||||
|
pane.items.removeRecursive.title=Remove from Collection and Subcollections
|
||||||
|
pane.items.removeRecursive=Are you sure you want to remove the selected item from this collection and all subcollections?
|
||||||
|
pane.items.removeRecursive.multiple=Are you sure you want to remove the selected items from this collection and all subcollections?
|
||||||
pane.items.menu.addNoteFromAnnotations=Add Note from Annotations
|
pane.items.menu.addNoteFromAnnotations=Add Note from Annotations
|
||||||
pane.items.menu.addNoteFromAnnotations.multiple=Add Notes from Annotations
|
pane.items.menu.createNoteFromAnnotations=Create Note from Annotations
|
||||||
pane.items.menu.findAvailablePDF=ابحث عن ملف PDF متاح
|
pane.items.menu.findAvailablePDF=ابحث عن ملف PDF متاح
|
||||||
pane.items.menu.findAvailablePDF.multiple=ابحث عن ملفات PDF متاحة
|
pane.items.menu.findAvailablePDF.multiple=ابحث عن ملفات PDF متاحة
|
||||||
pane.items.menu.addToCollection=Add to Collection
|
pane.items.menu.addToCollection=Add to Collection
|
||||||
|
|
@ -338,11 +343,13 @@ pane.items.menu.removeFromPublications=أزل العنصر من منشوراتي
|
||||||
pane.items.menu.removeFromPublications.multiple=أزل العناصر من منشوراتي...
|
pane.items.menu.removeFromPublications.multiple=أزل العناصر من منشوراتي...
|
||||||
pane.items.menu.moveToTrash=انقل العنصر لسلة المحذوفات...
|
pane.items.menu.moveToTrash=انقل العنصر لسلة المحذوفات...
|
||||||
pane.items.menu.moveToTrash.multiple=انقل العناصر لسلة المحذوفات...
|
pane.items.menu.moveToTrash.multiple=انقل العناصر لسلة المحذوفات...
|
||||||
pane.items.menu.delete=Delete Permanently…
|
pane.items.menu.delete=حذف نهائي...
|
||||||
pane.items.menu.export=تصدير العنصر المحدد...
|
pane.items.menu.export=تصدير العنصر المحدد...
|
||||||
pane.items.menu.export.multiple=تصدير العناصر المحددة...
|
pane.items.menu.export.multiple=تصدير العناصر المحددة...
|
||||||
pane.items.menu.exportNote=Export Note…
|
pane.items.menu.exportNote=Export Note…
|
||||||
pane.items.menu.exportNote.multiple=Export Notes…
|
pane.items.menu.exportNote.multiple=Export Notes…
|
||||||
|
pane.items.menu.exportPDF=Export PDF…
|
||||||
|
pane.items.menu.exportPDF.multiple=Export PDFs…
|
||||||
pane.items.menu.createBib=إنشاء ببليوجرافية من العنصر المحدد...
|
pane.items.menu.createBib=إنشاء ببليوجرافية من العنصر المحدد...
|
||||||
pane.items.menu.createBib.multiple=إنشاء ببليوجرافية من العناصر المحددة...
|
pane.items.menu.createBib.multiple=إنشاء ببليوجرافية من العناصر المحددة...
|
||||||
pane.items.menu.generateReport=انتاج تقرير من العنصر المحدد...
|
pane.items.menu.generateReport=انتاج تقرير من العنصر المحدد...
|
||||||
|
|
@ -355,6 +362,8 @@ pane.items.menu.createParent=انشئ عنصر رئيسي…
|
||||||
pane.items.menu.createParent.multiple=انشئ عناصر رئيسية
|
pane.items.menu.createParent.multiple=انشئ عناصر رئيسية
|
||||||
pane.items.menu.renameAttachments=إعادة تسمية الملف وفقا للبيانات الوصفية للعنصر الرئيسي
|
pane.items.menu.renameAttachments=إعادة تسمية الملف وفقا للبيانات الوصفية للعنصر الرئيسي
|
||||||
pane.items.menu.renameAttachments.multiple=إعادة تسمية الملفات وفقا للبيانات الوصفية للعنصر الرئيسي
|
pane.items.menu.renameAttachments.multiple=إعادة تسمية الملفات وفقا للبيانات الوصفية للعنصر الرئيسي
|
||||||
|
pane.items.menu.duplicateAndConvert.toBookSection=Create Book Section
|
||||||
|
pane.items.menu.duplicateAndConvert.toBook=Create Book from Book Section
|
||||||
pane.items.showItemInLibrary=عرض العنصر في المكتبة
|
pane.items.showItemInLibrary=عرض العنصر في المكتبة
|
||||||
|
|
||||||
pane.items.letter.oneParticipant=خطاب إلى %S
|
pane.items.letter.oneParticipant=خطاب إلى %S
|
||||||
|
|
@ -408,6 +417,16 @@ pane.item.attachments.fileNotFound.text2.stored=It may have been moved or delete
|
||||||
pane.item.attachments.fileNotFound.text2.stored.notOnServer=It may have been moved or deleted outside of %1$S, or, if the file was added on another computer, it may not yet have been synced to %2$S.
|
pane.item.attachments.fileNotFound.text2.stored.notOnServer=It may have been moved or deleted outside of %1$S, or, if the file was added on another computer, it may not yet have been synced to %2$S.
|
||||||
pane.item.attachments.fileNotFound.text2.linked=It may have been moved or deleted outside of %1$S, or a Linked Attachment Base Directory may be set incorrectly on one of your computers.
|
pane.item.attachments.fileNotFound.text2.linked=It may have been moved or deleted outside of %1$S, or a Linked Attachment Base Directory may be set incorrectly on one of your computers.
|
||||||
pane.item.attachments.delete.confirm=هل ترغب في حذف هذا المرفق؟
|
pane.item.attachments.delete.confirm=هل ترغب في حذف هذا المرفق؟
|
||||||
|
pane.item.attachments.autoRelink.title=File Located Automatically
|
||||||
|
pane.item.attachments.autoRelink.text1=The file could not be found at the specified location, but a file with the same name was found within your Linked Attachment Base Directory:
|
||||||
|
pane.item.attachments.autoRelink.text2=Old Location: %S
|
||||||
|
pane.item.attachments.autoRelink.text3=New Location: %S
|
||||||
|
pane.item.attachments.autoRelink.text4=%1$S can automatically relink this attachment.
|
||||||
|
pane.item.attachments.autoRelink.relink=Relink
|
||||||
|
pane.item.attachments.autoRelinkOthers.title=Additional Files Located
|
||||||
|
pane.item.attachments.autoRelinkOthers.text=One other unlinked attachment in this library was found within the same directory. Relink this attachment as well?;%S other unlinked attachments in this library were found within the same directory. Relink all located attachments?
|
||||||
|
pane.item.attachments.autoRelink.locateManually=Locate Manually…
|
||||||
|
pane.item.attachments.autoRelink.relinkAll=Relink All
|
||||||
pane.item.attachments.count.zero=لا توجد مرفقات:
|
pane.item.attachments.count.zero=لا توجد مرفقات:
|
||||||
pane.item.attachments.count.singular=%S مرفقات:
|
pane.item.attachments.count.singular=%S مرفقات:
|
||||||
pane.item.attachments.count.plural=%S مرفق:
|
pane.item.attachments.count.plural=%S مرفق:
|
||||||
|
|
@ -430,11 +449,11 @@ pane.item.related.count.zero=لا توجد ارتباطات:
|
||||||
pane.item.related.count.singular=%S ارتباطات:
|
pane.item.related.count.singular=%S ارتباطات:
|
||||||
pane.item.related.count.plural=%S ارتباط:
|
pane.item.related.count.plural=%S ارتباط:
|
||||||
pane.item.parentItem=عنصر رئيسي:
|
pane.item.parentItem=عنصر رئيسي:
|
||||||
pane.item.viewOnline.tooltip=Go to this item online
|
pane.item.viewOnline.tooltip=الذهاب لهذا العنصر على الانترنت
|
||||||
|
|
||||||
pane.context.noParent=No parent item
|
pane.context.noParent=No parent item
|
||||||
pane.context.itemNotes=Item Notes
|
pane.context.itemNotes=Item Notes
|
||||||
pane.context.allNotes=All Notes
|
pane.context.allNotes=كل الملاحظات
|
||||||
pane.context.noNotes=No notes
|
pane.context.noNotes=No notes
|
||||||
|
|
||||||
itemTypes.note=ملاحظة
|
itemTypes.note=ملاحظة
|
||||||
|
|
@ -547,7 +566,7 @@ itemFields.runningTime=وقت التشغيل
|
||||||
itemFields.network=الشبكة
|
itemFields.network=الشبكة
|
||||||
itemFields.postType=نوع الموضوع
|
itemFields.postType=نوع الموضوع
|
||||||
itemFields.audioFileType=نوع الملف الصوتي
|
itemFields.audioFileType=نوع الملف الصوتي
|
||||||
itemFields.versionNumber=Version
|
itemFields.versionNumber=الإصدارة
|
||||||
itemFields.system=النظام
|
itemFields.system=النظام
|
||||||
itemFields.company=الشركة
|
itemFields.company=الشركة
|
||||||
itemFields.conferenceName=اسم المؤتمر
|
itemFields.conferenceName=اسم المؤتمر
|
||||||
|
|
@ -719,6 +738,7 @@ zotero.preferences.export.quickCopy.citationStyles=أنماط الإستشهاد
|
||||||
zotero.preferences.export.quickCopy.exportFormats=صيغ التصدير
|
zotero.preferences.export.quickCopy.exportFormats=صيغ التصدير
|
||||||
zotero.preferences.export.quickCopy.instructions=النسخ السريع يسمح لك بتصدير العناصر في صيغة معينة. يمكن أن تنسخ العناصر المختارة إلى الحافظة بضغط %S أو سحب العناصر مباشرة داخل مربع نص في برنامج آخر.
|
zotero.preferences.export.quickCopy.instructions=النسخ السريع يسمح لك بتصدير العناصر في صيغة معينة. يمكن أن تنسخ العناصر المختارة إلى الحافظة بضغط %S أو سحب العناصر مباشرة داخل مربع نص في برنامج آخر.
|
||||||
zotero.preferences.export.quickCopy.citationInstructions=لأنماط الاستشهاد، يمكنك نسخ الاستشهادات أو الحواشي السفلية عن طريق الضغط على %S أو الضغط باستمرار على Shift قبل سحب العناصر.
|
zotero.preferences.export.quickCopy.citationInstructions=لأنماط الاستشهاد، يمكنك نسخ الاستشهادات أو الحواشي السفلية عن طريق الضغط على %S أو الضغط باستمرار على Shift قبل سحب العناصر.
|
||||||
|
zotero.preferences.export.quickCopy.note.htmlOptions.label=Rich Text/HTML
|
||||||
|
|
||||||
zotero.preferences.wordProcessors.installationSuccess=تم اكتمال التنصيب
|
zotero.preferences.wordProcessors.installationSuccess=تم اكتمال التنصيب
|
||||||
zotero.preferences.wordProcessors.installationError=Installation could not be completed because an error occurred. Please ensure that %1$S is closed, and then restart %2$S.
|
zotero.preferences.wordProcessors.installationError=Installation could not be completed because an error occurred. Please ensure that %1$S is closed, and then restart %2$S.
|
||||||
|
|
@ -757,7 +777,7 @@ zotero.debugOutputLogging.enabledAfterRestart=Debug output logging will be enabl
|
||||||
dragAndDrop.existingFiles=لم يتم نسخ الملفات التالية لأنها موجودة بالفعل في المجلد الهدف:
|
dragAndDrop.existingFiles=لم يتم نسخ الملفات التالية لأنها موجودة بالفعل في المجلد الهدف:
|
||||||
dragAndDrop.filesNotFound=لم يتم نسخ الملفات التالية لأنه لم يتم العثور عليها:
|
dragAndDrop.filesNotFound=لم يتم نسخ الملفات التالية لأنه لم يتم العثور عليها:
|
||||||
|
|
||||||
fileInterface.importing=Importing…
|
fileInterface.importing=استيراد...
|
||||||
fileInterface.importComplete=Import Complete
|
fileInterface.importComplete=Import Complete
|
||||||
fileInterface.itemsWereImported=%1$S item was imported;%1$S items were imported
|
fileInterface.itemsWereImported=%1$S item was imported;%1$S items were imported
|
||||||
fileInterface.itemsExported=تصدير العناصر...
|
fileInterface.itemsExported=تصدير العناصر...
|
||||||
|
|
@ -864,22 +884,7 @@ citation.showEditor=عرض المحرر...
|
||||||
citation.hideEditor=إخفاء المحرر...
|
citation.hideEditor=إخفاء المحرر...
|
||||||
citation.citations=استشهادات
|
citation.citations=استشهادات
|
||||||
citation.notes=ملاحظات
|
citation.notes=ملاحظات
|
||||||
citation.locator.page=صفحة
|
citation.locator.timestamp=Timestamp
|
||||||
citation.locator.book=كتاب
|
|
||||||
citation.locator.chapter=فصل
|
|
||||||
citation.locator.column=عمود
|
|
||||||
citation.locator.figure=شكل
|
|
||||||
citation.locator.folio=Folio
|
|
||||||
citation.locator.issue=اصدار
|
|
||||||
citation.locator.line=سطر
|
|
||||||
citation.locator.note=ملاحظة
|
|
||||||
citation.locator.opus=Opus
|
|
||||||
citation.locator.paragraph=فقرة
|
|
||||||
citation.locator.part=جزء
|
|
||||||
citation.locator.section=قسم
|
|
||||||
citation.locator.subverbo=Sub verbo
|
|
||||||
citation.locator.volume=مجلد
|
|
||||||
citation.locator.verse=Verse
|
|
||||||
|
|
||||||
report.title.default=تقرير زوتيرو
|
report.title.default=تقرير زوتيرو
|
||||||
report.parentItem=عنصر رئيسي:
|
report.parentItem=عنصر رئيسي:
|
||||||
|
|
@ -940,7 +945,7 @@ integration.error.misconfiguredWordStartupFolder.some=%S could not install the W
|
||||||
integration.error.misconfiguredWordStartupFolder.all=%S could not install the Word plugin because the Word Startup folder location is misconfigured.
|
integration.error.misconfiguredWordStartupFolder.all=%S could not install the Word plugin because the Word Startup folder location is misconfigured.
|
||||||
integration.error.misconfiguredWordStartupFolder.fix=The plugin may not appear in Word until you reset your Startup folder to the default location.
|
integration.error.misconfiguredWordStartupFolder.fix=The plugin may not appear in Word until you reset your Startup folder to the default location.
|
||||||
integration.error.macWordSBPermissionsMissing.title=إذن مفقود
|
integration.error.macWordSBPermissionsMissing.title=إذن مفقود
|
||||||
integration.error.macWordSBPermissionsMissing=Zotero does not have permission to control Word. To grant this permission:\n\n1) Open System Preferences\n2) Click on “Security & Privacy”\n3) Select the “Privacy” tab\n4) Find and select “Automation” on the left\n5) Check the checkbox for “Microsoft Word” under “Zotero”\n6) Restart Word
|
integration.error.macWordSBPermissionsMissing=Zotero does not have permission to control Word. To grant this permission:\n\n1) Open System Settings\n2) Select “Privacy & Security” in the left column\n3) Select “Automation”\n4) Find “Zotero” and click the arrow to expand it\n5) Make sure “Microsoft Word” is enabled under “Zotero”\n6) Restart Word
|
||||||
integration.error.macWordSBPermissionsMissing.pre2016=If “Microsoft Word” does not appear under “Automation”, make sure you are running Word 2011 version 14.7.7 or later.
|
integration.error.macWordSBPermissionsMissing.pre2016=If “Microsoft Word” does not appear under “Automation”, make sure you are running Word 2011 version 14.7.7 or later.
|
||||||
integration.error.m1UpgradeOS.title=macOS Upgrade Required
|
integration.error.m1UpgradeOS.title=macOS Upgrade Required
|
||||||
integration.error.m1UpgradeOS=Citing in Word on an Apple Silicon Mac with macOS 11.3 or earlier is not supported and may cause %S to freeze. Please upgrade to macOS 11.4 or later.
|
integration.error.m1UpgradeOS=Citing in Word on an Apple Silicon Mac with macOS 11.3 or earlier is not supported and may cause %S to freeze. Please upgrade to macOS 11.4 or later.
|
||||||
|
|
@ -1005,7 +1010,7 @@ sync.skipGroup=Skip Group
|
||||||
sync.removeGroupsAndSync=ازالة مجموعات المشاركة و المزامنة
|
sync.removeGroupsAndSync=ازالة مجموعات المشاركة و المزامنة
|
||||||
|
|
||||||
sync.reminder.setUp.message=Back up your library with %S syncing.
|
sync.reminder.setUp.message=Back up your library with %S syncing.
|
||||||
sync.reminder.setUp.action=Set Up Syncing
|
sync.reminder.setUp.action=إعداد المزامنة
|
||||||
sync.reminder.autoSync.message=%S hasn’t synced in a while. Do you want to enable automatic syncing?
|
sync.reminder.autoSync.message=%S hasn’t synced in a while. Do you want to enable automatic syncing?
|
||||||
|
|
||||||
sync.error.usernameNotSet=لم يتم تعيين اسم المستخدم
|
sync.error.usernameNotSet=لم يتم تعيين اسم المستخدم
|
||||||
|
|
@ -1072,8 +1077,8 @@ sync.conflict.tag.addedToLocal=It has been added to the following local items:
|
||||||
sync.conflict.localItem=Local Item
|
sync.conflict.localItem=Local Item
|
||||||
sync.conflict.remoteItem=Remote Item
|
sync.conflict.remoteItem=Remote Item
|
||||||
sync.conflict.mergedItem=Merged Item
|
sync.conflict.mergedItem=Merged Item
|
||||||
sync.conflict.localFile=Local File
|
sync.conflict.localFile=ملف محلي
|
||||||
sync.conflict.remoteFile=Remote File
|
sync.conflict.remoteFile=ملف عن بعد
|
||||||
sync.conflict.resolveAllLocal=Use the local version for all remaining conflicts
|
sync.conflict.resolveAllLocal=Use the local version for all remaining conflicts
|
||||||
sync.conflict.resolveAllRemote=Use the remote version for all remaining conflicts
|
sync.conflict.resolveAllRemote=Use the remote version for all remaining conflicts
|
||||||
sync.conflict.itemChanged=The following item has been changed in multiple locations. Click the version to use for resolving conflicting fields, and then click %S.
|
sync.conflict.itemChanged=The following item has been changed in multiple locations. Click the version to use for resolving conflicting fields, and then click %S.
|
||||||
|
|
@ -1124,7 +1129,7 @@ sync.storage.error.createNow=هل تريد إنشاؤه الآن؟
|
||||||
|
|
||||||
sync.storage.error.webdav.default=A WebDAV file sync error occurred. Please try syncing again.\n\nIf you receive this message repeatedly, check your WebDAV server settings in the Sync pane of the Zotero preferences.
|
sync.storage.error.webdav.default=A WebDAV file sync error occurred. Please try syncing again.\n\nIf you receive this message repeatedly, check your WebDAV server settings in the Sync pane of the Zotero preferences.
|
||||||
sync.storage.error.webdav.defaultRestart=A WebDAV file sync error occurred. Please restart %S and try syncing again.\n\nIf you receive this message repeatedly, check your WebDAV server settings in the Sync pane of the Zotero preferences.
|
sync.storage.error.webdav.defaultRestart=A WebDAV file sync error occurred. Please restart %S and try syncing again.\n\nIf you receive this message repeatedly, check your WebDAV server settings in the Sync pane of the Zotero preferences.
|
||||||
sync.storage.error.webdav.enterURL=Please enter a WebDAV URL.
|
sync.storage.error.webdav.enterURL=برجاء ادخال موقع WebDAV.
|
||||||
sync.storage.error.webdav.invalidURL=%S موقع WebDAV غير صالح.
|
sync.storage.error.webdav.invalidURL=%S موقع WebDAV غير صالح.
|
||||||
sync.storage.error.webdav.invalidLogin=لم يقبل خادم WebDAV اسم المستخدم وكلمة السر التي قمت بإدخالهما.
|
sync.storage.error.webdav.invalidLogin=لم يقبل خادم WebDAV اسم المستخدم وكلمة السر التي قمت بإدخالهما.
|
||||||
sync.storage.error.webdav.permissionDenied=ليس لديك الصلاحية للوصول الى %S على خادم WebDAV.
|
sync.storage.error.webdav.permissionDenied=ليس لديك الصلاحية للوصول الى %S على خادم WebDAV.
|
||||||
|
|
@ -1218,6 +1223,8 @@ locate.externalViewer.label=فتح في عارض خارجي
|
||||||
locate.internalViewer.label=فتح في العارض الداخلي
|
locate.internalViewer.label=فتح في العارض الداخلي
|
||||||
locate.showFile.label=عرض الملف
|
locate.showFile.label=عرض الملف
|
||||||
locate.libraryLookup.label=البحث في المكتبة
|
locate.libraryLookup.label=البحث في المكتبة
|
||||||
|
locate.libraryLookup.noResolver.title=No OpenURL Resolver
|
||||||
|
locate.libraryLookup.noResolver.text=You must choose an OpenURL resolver from the Advanced pane of the %S preferences.
|
||||||
locate.manageLocateEngines=إدارة محرك البحث...
|
locate.manageLocateEngines=إدارة محرك البحث...
|
||||||
locate.locateEngineDescription=Lookup engines help you find resources in your %S library on the web. Engines enabled in this list appear in the Locate drop-down in the toolbar.
|
locate.locateEngineDescription=Lookup engines help you find resources in your %S library on the web. Engines enabled in this list appear in the Locate drop-down in the toolbar.
|
||||||
|
|
||||||
|
|
@ -1293,9 +1300,9 @@ retraction.citationWarning=سُحِب أحد الاقتباسات في مستن
|
||||||
retraction.citationWarning.dontWarn=لا تحذرني حول هذا العنصر ثانية
|
retraction.citationWarning.dontWarn=لا تحذرني حول هذا العنصر ثانية
|
||||||
|
|
||||||
noteEditor.annotationsDateLine=(%S)
|
noteEditor.annotationsDateLine=(%S)
|
||||||
noteEditor.cut=Cut
|
noteEditor.cut=قص
|
||||||
noteEditor.copy=Copy
|
noteEditor.copy=نسخ
|
||||||
noteEditor.paste=Paste
|
noteEditor.paste=لصق
|
||||||
noteEditor.rightToLeft=Right to Left
|
noteEditor.rightToLeft=Right to Left
|
||||||
noteEditor.leftToRight=Left to Right
|
noteEditor.leftToRight=Left to Right
|
||||||
noteEditor.updateNotice=This note was edited with a newer version of %1$S.\nPlease update %1$S to make changes.
|
noteEditor.updateNotice=This note was edited with a newer version of %1$S.\nPlease update %1$S to make changes.
|
||||||
|
|
@ -1303,20 +1310,21 @@ noteEditor.enterLink=Enter Link
|
||||||
noteEditor.heading1=Heading 1
|
noteEditor.heading1=Heading 1
|
||||||
noteEditor.heading2=Heading 2
|
noteEditor.heading2=Heading 2
|
||||||
noteEditor.heading3=Heading 3
|
noteEditor.heading3=Heading 3
|
||||||
noteEditor.paragraph=Paragraph
|
noteEditor.paragraph=فقرة
|
||||||
noteEditor.monospaced=Monospaced
|
noteEditor.monospaced=Monospaced
|
||||||
noteEditor.bulletList=Bulleted List
|
noteEditor.bulletList=Bulleted List
|
||||||
noteEditor.orderedList=Numbered List
|
noteEditor.orderedList=Numbered List
|
||||||
noteEditor.blockquote=Block Quote
|
noteEditor.blockquote=Block Quote
|
||||||
|
noteEditor.mathBlock=Math Block
|
||||||
noteEditor.formatText=Format Text
|
noteEditor.formatText=Format Text
|
||||||
noteEditor.highlightText=Highlight Text
|
noteEditor.highlightText=تمييز النص
|
||||||
noteEditor.removeColor=Remove Color
|
noteEditor.removeColor=ازالة اللون
|
||||||
noteEditor.bold=Bold
|
noteEditor.bold=غامق
|
||||||
noteEditor.italic=Italic
|
noteEditor.italic=مائل
|
||||||
noteEditor.underline=Underline
|
noteEditor.underline=تسطير
|
||||||
noteEditor.strikethrough=Strikethrough
|
noteEditor.strikethrough=Strikethrough
|
||||||
noteEditor.subscript=Subscript
|
noteEditor.subscript=منخفض
|
||||||
noteEditor.superscript=Superscript
|
noteEditor.superscript=مرتفع
|
||||||
noteEditor.returnToNotesList=Return to Notes List
|
noteEditor.returnToNotesList=Return to Notes List
|
||||||
noteEditor.insertLink=Insert Link
|
noteEditor.insertLink=Insert Link
|
||||||
noteEditor.clearFormatting=Clear Formatting
|
noteEditor.clearFormatting=Clear Formatting
|
||||||
|
|
@ -1325,8 +1333,8 @@ noteEditor.alignLeft=Align Left
|
||||||
noteEditor.alignCenter=Align Center
|
noteEditor.alignCenter=Align Center
|
||||||
noteEditor.alignRight=Align Right
|
noteEditor.alignRight=Align Right
|
||||||
noteEditor.insertCitation=Insert Citation
|
noteEditor.insertCitation=Insert Citation
|
||||||
noteEditor.more=More
|
noteEditor.more=المزيد
|
||||||
noteEditor.find=Find
|
noteEditor.find=اعثر
|
||||||
noteEditor.replace=Replace
|
noteEditor.replace=Replace
|
||||||
noteEditor.previous=Previous
|
noteEditor.previous=Previous
|
||||||
noteEditor.next=Next
|
noteEditor.next=Next
|
||||||
|
|
@ -1338,7 +1346,7 @@ noteEditor.editCitation=Edit Citation
|
||||||
noteEditor.showOnPage=Show on Page
|
noteEditor.showOnPage=Show on Page
|
||||||
noteEditor.unlink=Unlink
|
noteEditor.unlink=Unlink
|
||||||
noteEditor.set=Set
|
noteEditor.set=Set
|
||||||
noteEditor.edit=Edit
|
noteEditor.edit=تحرير
|
||||||
noteEditor.addCitation=Add Citation
|
noteEditor.addCitation=Add Citation
|
||||||
noteEditor.removeCitation=Hide Citation
|
noteEditor.removeCitation=Hide Citation
|
||||||
noteEditor.findAndReplace=Find and Replace
|
noteEditor.findAndReplace=Find and Replace
|
||||||
|
|
@ -1347,7 +1355,11 @@ noteEditor.applyAnnotationColors=Show Annotation Colors
|
||||||
noteEditor.removeAnnotationColors=Hide Annotation Colors
|
noteEditor.removeAnnotationColors=Hide Annotation Colors
|
||||||
noteEditor.addCitations=Show Annotation Citations
|
noteEditor.addCitations=Show Annotation Citations
|
||||||
noteEditor.removeCitations=Hide Annotation Citations
|
noteEditor.removeCitations=Hide Annotation Citations
|
||||||
noteEditor.insertTable=Insert Table
|
noteEditor.image=صورة
|
||||||
|
noteEditor.math=Math
|
||||||
|
noteEditor.table=Table
|
||||||
|
noteEditor.copyImage=Copy Image
|
||||||
|
noteEditor.saveImageAs=Save Image As…
|
||||||
noteEditor.insertRowBefore=Insert Row Above
|
noteEditor.insertRowBefore=Insert Row Above
|
||||||
noteEditor.insertRowAfter=Insert Row Below
|
noteEditor.insertRowAfter=Insert Row Below
|
||||||
noteEditor.insertColumnBefore=Insert Column Left
|
noteEditor.insertColumnBefore=Insert Column Left
|
||||||
|
|
@ -1360,11 +1372,11 @@ pdfReader.annotations=Annotations
|
||||||
pdfReader.showAnnotations=عرض التعليقات
|
pdfReader.showAnnotations=عرض التعليقات
|
||||||
pdfReader.searchAnnotations=بحث في التعليقات
|
pdfReader.searchAnnotations=بحث في التعليقات
|
||||||
pdfReader.noAnnotations=Create an annotation to see it in the sidebar
|
pdfReader.noAnnotations=Create an annotation to see it in the sidebar
|
||||||
pdfReader.addText=Add extracted text
|
pdfReader.noExtractedText=No extracted text
|
||||||
pdfReader.addComment=Add comment
|
pdfReader.addComment=Add comment
|
||||||
pdfReader.addTags=Add tags…
|
pdfReader.addTags=Add tags…
|
||||||
pdfReader.highlightText=Highlight Text
|
pdfReader.highlightText=تمييز النص
|
||||||
pdfReader.addNote=Add Note
|
pdfReader.addNote=اضافة ملاحظة
|
||||||
pdfReader.selectArea=Select Area
|
pdfReader.selectArea=Select Area
|
||||||
pdfReader.pickColor=Pick a Color
|
pdfReader.pickColor=Pick a Color
|
||||||
pdfReader.addToNote=Add to Note
|
pdfReader.addToNote=Add to Note
|
||||||
|
|
@ -1373,17 +1385,26 @@ pdfReader.zoomOut=Zoom Out
|
||||||
pdfReader.zoomAuto=Automatically Resize
|
pdfReader.zoomAuto=Automatically Resize
|
||||||
pdfReader.zoomPageWidth=Zoom to Page Width
|
pdfReader.zoomPageWidth=Zoom to Page Width
|
||||||
pdfReader.zoomPageHeight=Zoom to Page Height
|
pdfReader.zoomPageHeight=Zoom to Page Height
|
||||||
|
pdfReader.splitVertically=Split Vertically
|
||||||
|
pdfReader.splitHorizontally=Split Horizontally
|
||||||
pdfReader.nextPage=Next Page
|
pdfReader.nextPage=Next Page
|
||||||
pdfReader.previousPage=Previous Page
|
pdfReader.previousPage=Previous Page
|
||||||
pdfReader.page=Page
|
pdfReader.page=صفحة
|
||||||
pdfReader.readOnly=Read-only
|
pdfReader.readOnly=Read-only
|
||||||
pdfReader.promptTransferFromPDF.title=Import Annotations
|
pdfReader.promptTransferFromPDF.title=Import Annotations
|
||||||
pdfReader.promptTransferFromPDF.text=Annotations stored in the PDF file will be moved to %1$S.
|
pdfReader.promptTransferFromPDF.text=Annotations stored in the PDF file will be moved to %1$S.
|
||||||
pdfReader.promptTransferToPDF.title=Store Annotations in File
|
pdfReader.promptTransferToPDF.title=Store Annotations in File
|
||||||
pdfReader.promptTransferToPDF.text=Annotations will be transferred to the PDF file and will no longer be editable in %S.
|
pdfReader.promptTransferToPDF.text=Annotations will be transferred to the PDF file and will no longer be editable in %S.
|
||||||
pdfReader.promptPasswordProtected=The operation is not supported for password-protected PDF files.
|
pdfReader.promptPasswordProtected=The operation is not supported for password-protected PDF files.
|
||||||
|
pdfReader.promptDeletePages.title=Delete Pages
|
||||||
|
pdfReader.promptDeletePages.text=Are you sure you want to delete %1$S page from the PDF file?;Are you sure you want to delete %1$S pages from the PDF file?
|
||||||
|
pdfReader.rotateLeft=Rotate Left
|
||||||
|
pdfReader.rotateRight=Rotate Right
|
||||||
|
pdfReader.rotate180=Rotate 180°
|
||||||
pdfReader.editPageNumber=Edit Page Number…
|
pdfReader.editPageNumber=Edit Page Number…
|
||||||
pdfReader.editHighlightedText=Edit Highlighted Text
|
pdfReader.editHighlightedText=Edit Highlighted Text
|
||||||
|
pdfReader.copyImage=Copy Image
|
||||||
|
pdfReader.saveImageAs=Save Image As…
|
||||||
pdfReader.pageNumberPopupHeader=Change page number for:
|
pdfReader.pageNumberPopupHeader=Change page number for:
|
||||||
pdfReader.thisAnnotation=هذا التعليق
|
pdfReader.thisAnnotation=هذا التعليق
|
||||||
pdfReader.selectedAnnotations=Selected annotations
|
pdfReader.selectedAnnotations=Selected annotations
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,24 @@
|
||||||
"general_done": {
|
"general_done": {
|
||||||
"message": "Готово"
|
"message": "Готово"
|
||||||
},
|
},
|
||||||
|
"general_yes": {
|
||||||
|
"message": "Да"
|
||||||
|
},
|
||||||
|
"general_no": {
|
||||||
|
"message": "Не"
|
||||||
|
},
|
||||||
"general_tryAgain": {
|
"general_tryAgain": {
|
||||||
"message": "Опитайте отново"
|
"message": "Опитайте отново"
|
||||||
},
|
},
|
||||||
|
"general_warning": {
|
||||||
|
"message": "Предупреждение"
|
||||||
|
},
|
||||||
"general_cancel": {
|
"general_cancel": {
|
||||||
"message": "Отказ"
|
"message": "Отказ"
|
||||||
},
|
},
|
||||||
|
"general_copyToClipboard": {
|
||||||
|
"message": "Копиране в клипборда"
|
||||||
|
},
|
||||||
"progressWindow_savingTo": {
|
"progressWindow_savingTo": {
|
||||||
"message": "Записване в"
|
"message": "Записване в"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<!ENTITY zotero.general.deselectAll "Отказ на всички">
|
<!ENTITY zotero.general.deselectAll "Отказ на всички">
|
||||||
<!ENTITY zotero.general.edit "Редактиране">
|
<!ENTITY zotero.general.edit "Редактиране">
|
||||||
<!ENTITY zotero.general.delete "Изтриване">
|
<!ENTITY zotero.general.delete "Изтриване">
|
||||||
<!ENTITY zotero.general.moveToTrash "Move to Trash">
|
<!ENTITY zotero.general.moveToTrash "Премества в кошчето за боклук">
|
||||||
<!ENTITY zotero.general.ok "OK">
|
<!ENTITY zotero.general.ok "OK">
|
||||||
<!ENTITY zotero.general.cancel "Отказ">
|
<!ENTITY zotero.general.cancel "Отказ">
|
||||||
<!ENTITY zotero.general.refresh "Опресняване">
|
<!ENTITY zotero.general.refresh "Опресняване">
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
<!ENTITY zotero.general.other "Други...">
|
<!ENTITY zotero.general.other "Други...">
|
||||||
<!ENTITY zotero.general.bigger "Bigger">
|
<!ENTITY zotero.general.bigger "Bigger">
|
||||||
<!ENTITY zotero.general.smaller "Smaller">
|
<!ENTITY zotero.general.smaller "Smaller">
|
||||||
<!ENTITY zotero.general.reset "Reset">
|
<!ENTITY zotero.general.reset "Нулиране">
|
||||||
|
|
||||||
|
|
||||||
<!ENTITY zotero.errorReport.title "Зотеро доклад за проблем">
|
<!ENTITY zotero.errorReport.title "Зотеро доклад за проблем">
|
||||||
|
|
@ -93,7 +93,7 @@
|
||||||
<!ENTITY zotero.toolbar.import.label "Внасяне...">
|
<!ENTITY zotero.toolbar.import.label "Внасяне...">
|
||||||
<!ENTITY zotero.toolbar.importFromClipboard "Внасяне от клипборда">
|
<!ENTITY zotero.toolbar.importFromClipboard "Внасяне от клипборда">
|
||||||
<!ENTITY zotero.toolbar.export.label "Изнасяне на библиотека...">
|
<!ENTITY zotero.toolbar.export.label "Изнасяне на библиотека...">
|
||||||
<!ENTITY zotero.toolbar.rtfScan.label "RTF Scan">
|
<!ENTITY zotero.toolbar.rtfScan.label "Сканиране на RTF">
|
||||||
<!ENTITY zotero.toolbar.timeline.label "Създаване на хронология">
|
<!ENTITY zotero.toolbar.timeline.label "Създаване на хронология">
|
||||||
<!ENTITY zotero.toolbar.preferences.label "Предпочитания...">
|
<!ENTITY zotero.toolbar.preferences.label "Предпочитания...">
|
||||||
<!ENTITY zotero.toolbar.supportAndDocumentation "Подръжка и документация">
|
<!ENTITY zotero.toolbar.supportAndDocumentation "Подръжка и документация">
|
||||||
|
|
@ -128,7 +128,7 @@
|
||||||
<!ENTITY zotero.toolbar.attachment.add "Запазване на копие от файл">
|
<!ENTITY zotero.toolbar.attachment.add "Запазване на копие от файл">
|
||||||
<!ENTITY zotero.toolbar.attachment.weblink "Запазване на връзка към настоящата страница">
|
<!ENTITY zotero.toolbar.attachment.weblink "Запазване на връзка към настоящата страница">
|
||||||
<!ENTITY zotero.toolbar.attachment.snapshot "Направи "моментна снимка" на настоящата страница">
|
<!ENTITY zotero.toolbar.attachment.snapshot "Направи "моментна снимка" на настоящата страница">
|
||||||
<!ENTITY zotero.toolbar.context.item "Item">
|
<!ENTITY zotero.toolbar.context.item "Елемент">
|
||||||
<!ENTITY zotero.toolbar.context.notes "Notes">
|
<!ENTITY zotero.toolbar.context.notes "Notes">
|
||||||
|
|
||||||
<!ENTITY zotero.tagSelector.noTagsToDisplay "Няма маркери, които да бъдат показани">
|
<!ENTITY zotero.tagSelector.noTagsToDisplay "Няма маркери, които да бъдат показани">
|
||||||
|
|
@ -185,7 +185,7 @@
|
||||||
<!ENTITY zotero.import.lastModified "Променено за последно">
|
<!ENTITY zotero.import.lastModified "Променено за последно">
|
||||||
<!ENTITY zotero.import.size "Размер">
|
<!ENTITY zotero.import.size "Размер">
|
||||||
<!ENTITY zotero.import.createCollection "Поместване на внесените колекции и записи в нова колекция">
|
<!ENTITY zotero.import.createCollection "Поместване на внесените колекции и записи в нова колекция">
|
||||||
<!ENTITY zotero.import.fileHandling "File Handling">
|
<!ENTITY zotero.import.fileHandling "Обработка на файловете">
|
||||||
|
|
||||||
<!ENTITY zotero.exportOptions.title "Изнасяне...">
|
<!ENTITY zotero.exportOptions.title "Изнасяне...">
|
||||||
<!ENTITY zotero.exportOptions.format.label "Формат:">
|
<!ENTITY zotero.exportOptions.format.label "Формат:">
|
||||||
|
|
@ -307,12 +307,10 @@
|
||||||
<!ENTITY zotero.context.addStandaloneNoteFromAnnotations "Add Standalone Note from Annotations">
|
<!ENTITY zotero.context.addStandaloneNoteFromAnnotations "Add Standalone Note from Annotations">
|
||||||
<!ENTITY zotero.context.editInWindow "Edit in a Separate Window">
|
<!ENTITY zotero.context.editInWindow "Edit in a Separate Window">
|
||||||
|
|
||||||
<!ENTITY zotero.pdfReader.firstPage "First Page">
|
<!ENTITY zotero.pdfReader.firstPage "Първа страница">
|
||||||
<!ENTITY zotero.pdfReader.lastPage "Last Page">
|
<!ENTITY zotero.pdfReader.lastPage "Last Page">
|
||||||
<!ENTITY zotero.pdfReader.back "Back">
|
<!ENTITY zotero.pdfReader.back "Back">
|
||||||
<!ENTITY zotero.pdfReader.forward "Forward">
|
<!ENTITY zotero.pdfReader.forward "Forward">
|
||||||
<!ENTITY zotero.pdfReader.rotateClockwise "Rotate Clockwise">
|
|
||||||
<!ENTITY zotero.pdfReader.rotateCounterclockwise "Rotate Counterclockwise">
|
|
||||||
<!ENTITY zotero.pdfReader.handTool "Hand Tool">
|
<!ENTITY zotero.pdfReader.handTool "Hand Tool">
|
||||||
<!ENTITY zotero.pdfReader.verticalScrolling "Vertical Scrolling">
|
<!ENTITY zotero.pdfReader.verticalScrolling "Vertical Scrolling">
|
||||||
<!ENTITY zotero.pdfReader.horizontalScrolling "Horizontal Scrolling">
|
<!ENTITY zotero.pdfReader.horizontalScrolling "Horizontal Scrolling">
|
||||||
|
|
@ -325,4 +323,9 @@
|
||||||
<!ENTITY zotero.pdfReader.zoomAuto "Automatically Resize">
|
<!ENTITY zotero.pdfReader.zoomAuto "Automatically Resize">
|
||||||
<!ENTITY zotero.pdfReader.zoomPageWidth "Zoom to Page Width">
|
<!ENTITY zotero.pdfReader.zoomPageWidth "Zoom to Page Width">
|
||||||
<!ENTITY zotero.pdfReader.zoomPageHeight "Zoom to Page Height">
|
<!ENTITY zotero.pdfReader.zoomPageHeight "Zoom to Page Height">
|
||||||
|
<!ENTITY zotero.pdfReader.splitVertically "Split Vertically">
|
||||||
|
<!ENTITY zotero.pdfReader.splitHorizontally "Split Horizontally">
|
||||||
<!ENTITY zotero.pdfReader.transferFromPDF "Import Annotations…">
|
<!ENTITY zotero.pdfReader.transferFromPDF "Import Annotations…">
|
||||||
|
<!ENTITY zotero.pdfReader.rotatePageLeft "Rotate Page Left">
|
||||||
|
<!ENTITY zotero.pdfReader.rotatePageRight "Rotate Page Right">
|
||||||
|
<!ENTITY zotero.pdfReader.rotatePage180 "Rotate Page 180°">
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ general.moreInformation=Повече информация
|
||||||
general.learnMore=Learn More
|
general.learnMore=Learn More
|
||||||
general.seeForMoreInformation=Вижте %S за повече информация.
|
general.seeForMoreInformation=Вижте %S за повече информация.
|
||||||
general.open=Отваряне на %S
|
general.open=Отваряне на %S
|
||||||
general.close=Close
|
general.close=Затвори
|
||||||
general.enable=Включване
|
general.enable=Включване
|
||||||
general.disable=Изключване
|
general.disable=Изключване
|
||||||
general.reset=Нулиране
|
general.reset=Нулиране
|
||||||
|
|
@ -71,7 +71,7 @@ general.fix=Поправяне…
|
||||||
general.tryAgain=Опит отново
|
general.tryAgain=Опит отново
|
||||||
general.tryLater=Опит по-късно
|
general.tryLater=Опит по-късно
|
||||||
general.showDirectory=Показване на директорията
|
general.showDirectory=Показване на директорията
|
||||||
general.showInLibrary=Show in Library
|
general.showInLibrary=Показване в библиотеката
|
||||||
general.continue=Продължаване
|
general.continue=Продължаване
|
||||||
general.copy=Copy
|
general.copy=Copy
|
||||||
general.copyToClipboard=Копиране в клипборда
|
general.copyToClipboard=Копиране в клипборда
|
||||||
|
|
@ -89,9 +89,10 @@ general.back=Back
|
||||||
general.languages=Languages
|
general.languages=Languages
|
||||||
general.default=Default
|
general.default=Default
|
||||||
general.custom=Custom
|
general.custom=Custom
|
||||||
general.loading=Loading…
|
general.loading=Зареждане...
|
||||||
general.richText=Rich Text
|
general.richText=Rich Text
|
||||||
general.clearSelection=Clear Selection
|
general.clearSelection=Clear Selection
|
||||||
|
general.insert=Insert
|
||||||
|
|
||||||
general.yellow=Yellow
|
general.yellow=Yellow
|
||||||
general.red=Red
|
general.red=Red
|
||||||
|
|
@ -114,6 +115,7 @@ about.getInvolved=Искате да помогнете? [Включете се]
|
||||||
punctuation.openingQMark=“
|
punctuation.openingQMark=“
|
||||||
punctuation.closingQMark=”
|
punctuation.closingQMark=”
|
||||||
punctuation.colon=:
|
punctuation.colon=:
|
||||||
|
punctuation.colon.withString=%S:
|
||||||
punctuation.ellipsis=…
|
punctuation.ellipsis=…
|
||||||
|
|
||||||
install.quickStartGuide=Кратко ръководство за начинаещи
|
install.quickStartGuide=Кратко ръководство за начинаещи
|
||||||
|
|
@ -327,8 +329,11 @@ pane.items.remove.multiple=Are you sure you want to remove the selected items fr
|
||||||
pane.items.removeFromPublications.title=Remove from My Publications
|
pane.items.removeFromPublications.title=Remove from My Publications
|
||||||
pane.items.removeFromPublications=Are you sure you want to remove the selected item from My Publications?
|
pane.items.removeFromPublications=Are you sure you want to remove the selected item from My Publications?
|
||||||
pane.items.removeFromPublications.multiple=Are you sure you want to remove the selected items from My Publications?
|
pane.items.removeFromPublications.multiple=Are you sure you want to remove the selected items from My Publications?
|
||||||
|
pane.items.removeRecursive.title=Remove from Collection and Subcollections
|
||||||
|
pane.items.removeRecursive=Are you sure you want to remove the selected item from this collection and all subcollections?
|
||||||
|
pane.items.removeRecursive.multiple=Are you sure you want to remove the selected items from this collection and all subcollections?
|
||||||
pane.items.menu.addNoteFromAnnotations=Add Note from Annotations
|
pane.items.menu.addNoteFromAnnotations=Add Note from Annotations
|
||||||
pane.items.menu.addNoteFromAnnotations.multiple=Add Notes from Annotations
|
pane.items.menu.createNoteFromAnnotations=Create Note from Annotations
|
||||||
pane.items.menu.findAvailablePDF=Find Available PDF
|
pane.items.menu.findAvailablePDF=Find Available PDF
|
||||||
pane.items.menu.findAvailablePDF.multiple=Find Available PDFs
|
pane.items.menu.findAvailablePDF.multiple=Find Available PDFs
|
||||||
pane.items.menu.addToCollection=Add to Collection
|
pane.items.menu.addToCollection=Add to Collection
|
||||||
|
|
@ -338,11 +343,13 @@ pane.items.menu.removeFromPublications=Remove Item from My Publications…
|
||||||
pane.items.menu.removeFromPublications.multiple=Remove Items from My Publications…
|
pane.items.menu.removeFromPublications.multiple=Remove Items from My Publications…
|
||||||
pane.items.menu.moveToTrash=Move Item to Trash…
|
pane.items.menu.moveToTrash=Move Item to Trash…
|
||||||
pane.items.menu.moveToTrash.multiple=Move Items to Trash…
|
pane.items.menu.moveToTrash.multiple=Move Items to Trash…
|
||||||
pane.items.menu.delete=Delete Permanently…
|
pane.items.menu.delete=Изтриване окончателно...
|
||||||
pane.items.menu.export=Експорт на избрания запис...
|
pane.items.menu.export=Експорт на избрания запис...
|
||||||
pane.items.menu.export.multiple=Експорт на избраните записи...
|
pane.items.menu.export.multiple=Експорт на избраните записи...
|
||||||
pane.items.menu.exportNote=Export Note…
|
pane.items.menu.exportNote=Export Note…
|
||||||
pane.items.menu.exportNote.multiple=Export Notes…
|
pane.items.menu.exportNote.multiple=Export Notes…
|
||||||
|
pane.items.menu.exportPDF=Export PDF…
|
||||||
|
pane.items.menu.exportPDF.multiple=Export PDFs…
|
||||||
pane.items.menu.createBib=Създава библиография от избрания запис...
|
pane.items.menu.createBib=Създава библиография от избрания запис...
|
||||||
pane.items.menu.createBib.multiple=Създава библиография от избраните записи...
|
pane.items.menu.createBib.multiple=Създава библиография от избраните записи...
|
||||||
pane.items.menu.generateReport=Създава отчет от избрания запис...
|
pane.items.menu.generateReport=Създава отчет от избрания запис...
|
||||||
|
|
@ -355,6 +362,8 @@ pane.items.menu.createParent=Create Parent Item…
|
||||||
pane.items.menu.createParent.multiple=Create Parent Items
|
pane.items.menu.createParent.multiple=Create Parent Items
|
||||||
pane.items.menu.renameAttachments=Преименува файла въз основа на родителските метадани
|
pane.items.menu.renameAttachments=Преименува файла въз основа на родителските метадани
|
||||||
pane.items.menu.renameAttachments.multiple=Преименува файловете въз основа на родителските метадани
|
pane.items.menu.renameAttachments.multiple=Преименува файловете въз основа на родителските метадани
|
||||||
|
pane.items.menu.duplicateAndConvert.toBookSection=Create Book Section
|
||||||
|
pane.items.menu.duplicateAndConvert.toBook=Create Book from Book Section
|
||||||
pane.items.showItemInLibrary=Show Item in Library
|
pane.items.showItemInLibrary=Show Item in Library
|
||||||
|
|
||||||
pane.items.letter.oneParticipant=Писмо до %S
|
pane.items.letter.oneParticipant=Писмо до %S
|
||||||
|
|
@ -408,6 +417,16 @@ pane.item.attachments.fileNotFound.text2.stored=It may have been moved or delete
|
||||||
pane.item.attachments.fileNotFound.text2.stored.notOnServer=It may have been moved or deleted outside of %1$S, or, if the file was added on another computer, it may not yet have been synced to %2$S.
|
pane.item.attachments.fileNotFound.text2.stored.notOnServer=It may have been moved or deleted outside of %1$S, or, if the file was added on another computer, it may not yet have been synced to %2$S.
|
||||||
pane.item.attachments.fileNotFound.text2.linked=It may have been moved or deleted outside of %1$S, or a Linked Attachment Base Directory may be set incorrectly on one of your computers.
|
pane.item.attachments.fileNotFound.text2.linked=It may have been moved or deleted outside of %1$S, or a Linked Attachment Base Directory may be set incorrectly on one of your computers.
|
||||||
pane.item.attachments.delete.confirm=Сигурни ли сте, че искате да изтриете това приложение?
|
pane.item.attachments.delete.confirm=Сигурни ли сте, че искате да изтриете това приложение?
|
||||||
|
pane.item.attachments.autoRelink.title=File Located Automatically
|
||||||
|
pane.item.attachments.autoRelink.text1=The file could not be found at the specified location, but a file with the same name was found within your Linked Attachment Base Directory:
|
||||||
|
pane.item.attachments.autoRelink.text2=Old Location: %S
|
||||||
|
pane.item.attachments.autoRelink.text3=New Location: %S
|
||||||
|
pane.item.attachments.autoRelink.text4=%1$S can automatically relink this attachment.
|
||||||
|
pane.item.attachments.autoRelink.relink=Relink
|
||||||
|
pane.item.attachments.autoRelinkOthers.title=Additional Files Located
|
||||||
|
pane.item.attachments.autoRelinkOthers.text=One other unlinked attachment in this library was found within the same directory. Relink this attachment as well?;%S other unlinked attachments in this library were found within the same directory. Relink all located attachments?
|
||||||
|
pane.item.attachments.autoRelink.locateManually=Locate Manually…
|
||||||
|
pane.item.attachments.autoRelink.relinkAll=Relink All
|
||||||
pane.item.attachments.count.zero=%S приложения:
|
pane.item.attachments.count.zero=%S приложения:
|
||||||
pane.item.attachments.count.singular=%S приложение:
|
pane.item.attachments.count.singular=%S приложение:
|
||||||
pane.item.attachments.count.plural=%S приложения:
|
pane.item.attachments.count.plural=%S приложения:
|
||||||
|
|
@ -438,7 +457,7 @@ pane.context.allNotes=All Notes
|
||||||
pane.context.noNotes=No notes
|
pane.context.noNotes=No notes
|
||||||
|
|
||||||
itemTypes.note=Бележка
|
itemTypes.note=Бележка
|
||||||
itemTypes.annotation=Annotation
|
itemTypes.annotation=Анотация
|
||||||
itemTypes.attachment=Приложение
|
itemTypes.attachment=Приложение
|
||||||
itemTypes.book=Книга
|
itemTypes.book=Книга
|
||||||
itemTypes.bookSection=Глава от книга
|
itemTypes.bookSection=Глава от книга
|
||||||
|
|
@ -719,6 +738,7 @@ zotero.preferences.export.quickCopy.citationStyles=Citation Styles
|
||||||
zotero.preferences.export.quickCopy.exportFormats=Формати за износ
|
zotero.preferences.export.quickCopy.exportFormats=Формати за износ
|
||||||
zotero.preferences.export.quickCopy.instructions=Quick Copy allows you to quickly export items in a given format. You can copy selected items to the clipboard by pressing %S or drag items directly into a text box in another program.
|
zotero.preferences.export.quickCopy.instructions=Quick Copy allows you to quickly export items in a given format. You can copy selected items to the clipboard by pressing %S or drag items directly into a text box in another program.
|
||||||
zotero.preferences.export.quickCopy.citationInstructions=For citation styles, you can copy citations or footnotes by pressing %S or holding down Shift before dragging items.
|
zotero.preferences.export.quickCopy.citationInstructions=For citation styles, you can copy citations or footnotes by pressing %S or holding down Shift before dragging items.
|
||||||
|
zotero.preferences.export.quickCopy.note.htmlOptions.label=Rich Text/HTML
|
||||||
|
|
||||||
zotero.preferences.wordProcessors.installationSuccess=Installation was successful.
|
zotero.preferences.wordProcessors.installationSuccess=Installation was successful.
|
||||||
zotero.preferences.wordProcessors.installationError=Installation could not be completed because an error occurred. Please ensure that %1$S is closed, and then restart %2$S.
|
zotero.preferences.wordProcessors.installationError=Installation could not be completed because an error occurred. Please ensure that %1$S is closed, and then restart %2$S.
|
||||||
|
|
@ -864,22 +884,7 @@ citation.showEditor=Показва редактора...
|
||||||
citation.hideEditor=Скрива редактора...
|
citation.hideEditor=Скрива редактора...
|
||||||
citation.citations=Citations
|
citation.citations=Citations
|
||||||
citation.notes=Notes
|
citation.notes=Notes
|
||||||
citation.locator.page=Page
|
citation.locator.timestamp=Timestamp
|
||||||
citation.locator.book=Book
|
|
||||||
citation.locator.chapter=Chapter
|
|
||||||
citation.locator.column=Column
|
|
||||||
citation.locator.figure=Figure
|
|
||||||
citation.locator.folio=Folio
|
|
||||||
citation.locator.issue=Issue
|
|
||||||
citation.locator.line=Line
|
|
||||||
citation.locator.note=Note
|
|
||||||
citation.locator.opus=Opus
|
|
||||||
citation.locator.paragraph=Paragraph
|
|
||||||
citation.locator.part=Part
|
|
||||||
citation.locator.section=Section
|
|
||||||
citation.locator.subverbo=Sub verbo
|
|
||||||
citation.locator.volume=Volume
|
|
||||||
citation.locator.verse=Verse
|
|
||||||
|
|
||||||
report.title.default=Зотеро отчет
|
report.title.default=Зотеро отчет
|
||||||
report.parentItem=Родителски запис:
|
report.parentItem=Родителски запис:
|
||||||
|
|
@ -940,7 +945,7 @@ integration.error.misconfiguredWordStartupFolder.some=%S could not install the W
|
||||||
integration.error.misconfiguredWordStartupFolder.all=%S could not install the Word plugin because the Word Startup folder location is misconfigured.
|
integration.error.misconfiguredWordStartupFolder.all=%S could not install the Word plugin because the Word Startup folder location is misconfigured.
|
||||||
integration.error.misconfiguredWordStartupFolder.fix=The plugin may not appear in Word until you reset your Startup folder to the default location.
|
integration.error.misconfiguredWordStartupFolder.fix=The plugin may not appear in Word until you reset your Startup folder to the default location.
|
||||||
integration.error.macWordSBPermissionsMissing.title=Missing Permission
|
integration.error.macWordSBPermissionsMissing.title=Missing Permission
|
||||||
integration.error.macWordSBPermissionsMissing=Zotero does not have permission to control Word. To grant this permission:\n\n1) Open System Preferences\n2) Click on “Security & Privacy”\n3) Select the “Privacy” tab\n4) Find and select “Automation” on the left\n5) Check the checkbox for “Microsoft Word” under “Zotero”\n6) Restart Word
|
integration.error.macWordSBPermissionsMissing=Zotero does not have permission to control Word. To grant this permission:\n\n1) Open System Settings\n2) Select “Privacy & Security” in the left column\n3) Select “Automation”\n4) Find “Zotero” and click the arrow to expand it\n5) Make sure “Microsoft Word” is enabled under “Zotero”\n6) Restart Word
|
||||||
integration.error.macWordSBPermissionsMissing.pre2016=If “Microsoft Word” does not appear under “Automation”, make sure you are running Word 2011 version 14.7.7 or later.
|
integration.error.macWordSBPermissionsMissing.pre2016=If “Microsoft Word” does not appear under “Automation”, make sure you are running Word 2011 version 14.7.7 or later.
|
||||||
integration.error.m1UpgradeOS.title=macOS Upgrade Required
|
integration.error.m1UpgradeOS.title=macOS Upgrade Required
|
||||||
integration.error.m1UpgradeOS=Citing in Word on an Apple Silicon Mac with macOS 11.3 or earlier is not supported and may cause %S to freeze. Please upgrade to macOS 11.4 or later.
|
integration.error.m1UpgradeOS=Citing in Word on an Apple Silicon Mac with macOS 11.3 or earlier is not supported and may cause %S to freeze. Please upgrade to macOS 11.4 or later.
|
||||||
|
|
@ -1005,7 +1010,7 @@ sync.skipGroup=Skip Group
|
||||||
sync.removeGroupsAndSync=Отстранява групите и синхронизация
|
sync.removeGroupsAndSync=Отстранява групите и синхронизация
|
||||||
|
|
||||||
sync.reminder.setUp.message=Back up your library with %S syncing.
|
sync.reminder.setUp.message=Back up your library with %S syncing.
|
||||||
sync.reminder.setUp.action=Set Up Syncing
|
sync.reminder.setUp.action=Настройване на синхронизирането
|
||||||
sync.reminder.autoSync.message=%S hasn’t synced in a while. Do you want to enable automatic syncing?
|
sync.reminder.autoSync.message=%S hasn’t synced in a while. Do you want to enable automatic syncing?
|
||||||
|
|
||||||
sync.error.usernameNotSet=Потребителското име не е въведено
|
sync.error.usernameNotSet=Потребителското име не е въведено
|
||||||
|
|
@ -1176,10 +1181,10 @@ recognizePDF.couldNotRead=Текста на този PDF файл не може
|
||||||
recognizePDF.noMatches=No matching references found
|
recognizePDF.noMatches=No matching references found
|
||||||
recognizePDF.fileNotFound=File not found
|
recognizePDF.fileNotFound=File not found
|
||||||
recognizePDF.error=An unexpected error occurred
|
recognizePDF.error=An unexpected error occurred
|
||||||
recognizePDF.recognizing.label=Retrieving Metadata…
|
recognizePDF.recognizing.label=Извлича на метаданите...
|
||||||
recognizePDF.complete.label=Metadata Retrieval Complete
|
recognizePDF.complete.label=Metadata Retrieval Complete
|
||||||
recognizePDF.pdfName.label=PDF Name
|
recognizePDF.pdfName.label=Име на PDF
|
||||||
recognizePDF.itemName.label=Item Name
|
recognizePDF.itemName.label=Име на запис
|
||||||
|
|
||||||
rtfScan.openTitle=Изберете файл, който да бъде сканиран
|
rtfScan.openTitle=Изберете файл, който да бъде сканиран
|
||||||
rtfScan.scanning.label=Сканира RTF документ...
|
rtfScan.scanning.label=Сканира RTF документ...
|
||||||
|
|
@ -1218,6 +1223,8 @@ locate.externalViewer.label=Open in External Viewer
|
||||||
locate.internalViewer.label=Open in Internal Viewer
|
locate.internalViewer.label=Open in Internal Viewer
|
||||||
locate.showFile.label=Show File
|
locate.showFile.label=Show File
|
||||||
locate.libraryLookup.label=Library Lookup
|
locate.libraryLookup.label=Library Lookup
|
||||||
|
locate.libraryLookup.noResolver.title=No OpenURL Resolver
|
||||||
|
locate.libraryLookup.noResolver.text=You must choose an OpenURL resolver from the Advanced pane of the %S preferences.
|
||||||
locate.manageLocateEngines=Manage Lookup Engines...
|
locate.manageLocateEngines=Manage Lookup Engines...
|
||||||
locate.locateEngineDescription=Lookup engines help you find resources in your %S library on the web. Engines enabled in this list appear in the Locate drop-down in the toolbar.
|
locate.locateEngineDescription=Lookup engines help you find resources in your %S library on the web. Engines enabled in this list appear in the Locate drop-down in the toolbar.
|
||||||
|
|
||||||
|
|
@ -1308,15 +1315,16 @@ noteEditor.monospaced=Monospaced
|
||||||
noteEditor.bulletList=Bulleted List
|
noteEditor.bulletList=Bulleted List
|
||||||
noteEditor.orderedList=Numbered List
|
noteEditor.orderedList=Numbered List
|
||||||
noteEditor.blockquote=Block Quote
|
noteEditor.blockquote=Block Quote
|
||||||
|
noteEditor.mathBlock=Math Block
|
||||||
noteEditor.formatText=Format Text
|
noteEditor.formatText=Format Text
|
||||||
noteEditor.highlightText=Highlight Text
|
noteEditor.highlightText=Акцентиране на текст
|
||||||
noteEditor.removeColor=Remove Color
|
noteEditor.removeColor=Премахване на цвят
|
||||||
noteEditor.bold=Bold
|
noteEditor.bold=Удебелен
|
||||||
noteEditor.italic=Italic
|
noteEditor.italic=Наклонен
|
||||||
noteEditor.underline=Underline
|
noteEditor.underline=Подчертан
|
||||||
noteEditor.strikethrough=Strikethrough
|
noteEditor.strikethrough=Strikethrough
|
||||||
noteEditor.subscript=Subscript
|
noteEditor.subscript=Субскрипт / Долни букви
|
||||||
noteEditor.superscript=Superscript
|
noteEditor.superscript=Суперскрипт / Горни букви
|
||||||
noteEditor.returnToNotesList=Return to Notes List
|
noteEditor.returnToNotesList=Return to Notes List
|
||||||
noteEditor.insertLink=Insert Link
|
noteEditor.insertLink=Insert Link
|
||||||
noteEditor.clearFormatting=Clear Formatting
|
noteEditor.clearFormatting=Clear Formatting
|
||||||
|
|
@ -1325,7 +1333,7 @@ noteEditor.alignLeft=Align Left
|
||||||
noteEditor.alignCenter=Align Center
|
noteEditor.alignCenter=Align Center
|
||||||
noteEditor.alignRight=Align Right
|
noteEditor.alignRight=Align Right
|
||||||
noteEditor.insertCitation=Insert Citation
|
noteEditor.insertCitation=Insert Citation
|
||||||
noteEditor.more=More
|
noteEditor.more=Още
|
||||||
noteEditor.find=Find
|
noteEditor.find=Find
|
||||||
noteEditor.replace=Replace
|
noteEditor.replace=Replace
|
||||||
noteEditor.previous=Previous
|
noteEditor.previous=Previous
|
||||||
|
|
@ -1338,7 +1346,7 @@ noteEditor.editCitation=Edit Citation
|
||||||
noteEditor.showOnPage=Show on Page
|
noteEditor.showOnPage=Show on Page
|
||||||
noteEditor.unlink=Unlink
|
noteEditor.unlink=Unlink
|
||||||
noteEditor.set=Set
|
noteEditor.set=Set
|
||||||
noteEditor.edit=Edit
|
noteEditor.edit=Редактиране
|
||||||
noteEditor.addCitation=Add Citation
|
noteEditor.addCitation=Add Citation
|
||||||
noteEditor.removeCitation=Hide Citation
|
noteEditor.removeCitation=Hide Citation
|
||||||
noteEditor.findAndReplace=Find and Replace
|
noteEditor.findAndReplace=Find and Replace
|
||||||
|
|
@ -1347,7 +1355,11 @@ noteEditor.applyAnnotationColors=Show Annotation Colors
|
||||||
noteEditor.removeAnnotationColors=Hide Annotation Colors
|
noteEditor.removeAnnotationColors=Hide Annotation Colors
|
||||||
noteEditor.addCitations=Show Annotation Citations
|
noteEditor.addCitations=Show Annotation Citations
|
||||||
noteEditor.removeCitations=Hide Annotation Citations
|
noteEditor.removeCitations=Hide Annotation Citations
|
||||||
noteEditor.insertTable=Insert Table
|
noteEditor.image=Образ
|
||||||
|
noteEditor.math=Math
|
||||||
|
noteEditor.table=Table
|
||||||
|
noteEditor.copyImage=Copy Image
|
||||||
|
noteEditor.saveImageAs=Save Image As…
|
||||||
noteEditor.insertRowBefore=Insert Row Above
|
noteEditor.insertRowBefore=Insert Row Above
|
||||||
noteEditor.insertRowAfter=Insert Row Below
|
noteEditor.insertRowAfter=Insert Row Below
|
||||||
noteEditor.insertColumnBefore=Insert Column Left
|
noteEditor.insertColumnBefore=Insert Column Left
|
||||||
|
|
@ -1360,11 +1372,11 @@ pdfReader.annotations=Annotations
|
||||||
pdfReader.showAnnotations=Show Annotations
|
pdfReader.showAnnotations=Show Annotations
|
||||||
pdfReader.searchAnnotations=Search Annotations
|
pdfReader.searchAnnotations=Search Annotations
|
||||||
pdfReader.noAnnotations=Create an annotation to see it in the sidebar
|
pdfReader.noAnnotations=Create an annotation to see it in the sidebar
|
||||||
pdfReader.addText=Add extracted text
|
pdfReader.noExtractedText=No extracted text
|
||||||
pdfReader.addComment=Add comment
|
pdfReader.addComment=Add comment
|
||||||
pdfReader.addTags=Add tags…
|
pdfReader.addTags=Add tags…
|
||||||
pdfReader.highlightText=Highlight Text
|
pdfReader.highlightText=Акцентиране на текст
|
||||||
pdfReader.addNote=Add Note
|
pdfReader.addNote=Добавяне на бележка
|
||||||
pdfReader.selectArea=Select Area
|
pdfReader.selectArea=Select Area
|
||||||
pdfReader.pickColor=Pick a Color
|
pdfReader.pickColor=Pick a Color
|
||||||
pdfReader.addToNote=Add to Note
|
pdfReader.addToNote=Add to Note
|
||||||
|
|
@ -1373,6 +1385,8 @@ pdfReader.zoomOut=Zoom Out
|
||||||
pdfReader.zoomAuto=Automatically Resize
|
pdfReader.zoomAuto=Automatically Resize
|
||||||
pdfReader.zoomPageWidth=Zoom to Page Width
|
pdfReader.zoomPageWidth=Zoom to Page Width
|
||||||
pdfReader.zoomPageHeight=Zoom to Page Height
|
pdfReader.zoomPageHeight=Zoom to Page Height
|
||||||
|
pdfReader.splitVertically=Split Vertically
|
||||||
|
pdfReader.splitHorizontally=Split Horizontally
|
||||||
pdfReader.nextPage=Next Page
|
pdfReader.nextPage=Next Page
|
||||||
pdfReader.previousPage=Previous Page
|
pdfReader.previousPage=Previous Page
|
||||||
pdfReader.page=Page
|
pdfReader.page=Page
|
||||||
|
|
@ -1382,8 +1396,15 @@ pdfReader.promptTransferFromPDF.text=Annotations stored in the PDF file will be
|
||||||
pdfReader.promptTransferToPDF.title=Store Annotations in File
|
pdfReader.promptTransferToPDF.title=Store Annotations in File
|
||||||
pdfReader.promptTransferToPDF.text=Annotations will be transferred to the PDF file and will no longer be editable in %S.
|
pdfReader.promptTransferToPDF.text=Annotations will be transferred to the PDF file and will no longer be editable in %S.
|
||||||
pdfReader.promptPasswordProtected=The operation is not supported for password-protected PDF files.
|
pdfReader.promptPasswordProtected=The operation is not supported for password-protected PDF files.
|
||||||
|
pdfReader.promptDeletePages.title=Delete Pages
|
||||||
|
pdfReader.promptDeletePages.text=Are you sure you want to delete %1$S page from the PDF file?;Are you sure you want to delete %1$S pages from the PDF file?
|
||||||
|
pdfReader.rotateLeft=Rotate Left
|
||||||
|
pdfReader.rotateRight=Rotate Right
|
||||||
|
pdfReader.rotate180=Rotate 180°
|
||||||
pdfReader.editPageNumber=Edit Page Number…
|
pdfReader.editPageNumber=Edit Page Number…
|
||||||
pdfReader.editHighlightedText=Edit Highlighted Text
|
pdfReader.editHighlightedText=Edit Highlighted Text
|
||||||
|
pdfReader.copyImage=Copy Image
|
||||||
|
pdfReader.saveImageAs=Save Image As…
|
||||||
pdfReader.pageNumberPopupHeader=Change page number for:
|
pdfReader.pageNumberPopupHeader=Change page number for:
|
||||||
pdfReader.thisAnnotation=This annotation
|
pdfReader.thisAnnotation=This annotation
|
||||||
pdfReader.selectedAnnotations=Selected annotations
|
pdfReader.selectedAnnotations=Selected annotations
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<!ENTITY zotero.developers "Diorroerien:">
|
<!ENTITY zotero.developers "Diorroerien:">
|
||||||
<!ENTITY zotero.alumni "Kendaolerien gozh:">
|
<!ENTITY zotero.alumni "Kendaolerien gozh:">
|
||||||
<!ENTITY zotero.about.localizations "Lec'heladurioù:">
|
<!ENTITY zotero.about.localizations "Lec'heladurioù:">
|
||||||
<!ENTITY zotero.about.additionalSoftware "Third-Party Software:">
|
<!ENTITY zotero.about.additionalSoftware "Meziantoù tredeel:">
|
||||||
<!ENTITY zotero.thanks "Trugarez vras da:">
|
<!ENTITY zotero.thanks "Trugarez vras da:">
|
||||||
<!ENTITY zotero.about.close "Serriñ">
|
<!ENTITY zotero.about.close "Serriñ">
|
||||||
<!ENTITY zotero.moreCreditsAndAcknowledgements "Muioc'h a greditoù & trugarekadurioù">
|
<!ENTITY zotero.moreCreditsAndAcknowledgements "Muioc'h a greditoù & trugarekadurioù">
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,12 @@
|
||||||
"general_more": {
|
"general_more": {
|
||||||
"message": "Muioc'h..."
|
"message": "Muioc'h..."
|
||||||
},
|
},
|
||||||
|
"general_moreInfo": {
|
||||||
|
"message": "Muioc'h a ditouroù..."
|
||||||
|
},
|
||||||
|
"general_needHelp": {
|
||||||
|
"message": "Ezhomm ho peus sikour?"
|
||||||
|
},
|
||||||
"general_done": {
|
"general_done": {
|
||||||
"message": "Graet"
|
"message": "Graet"
|
||||||
},
|
},
|
||||||
|
|
@ -23,6 +29,9 @@
|
||||||
"general_pleaseWait": {
|
"general_pleaseWait": {
|
||||||
"message": "Gortozit mar plij..."
|
"message": "Gortozit mar plij..."
|
||||||
},
|
},
|
||||||
|
"general_copyToClipboard": {
|
||||||
|
"message": "Eilañ er golver"
|
||||||
|
},
|
||||||
"progressWindow_savingTo": {
|
"progressWindow_savingTo": {
|
||||||
"message": "Enrollañ e-barzh"
|
"message": "Enrollañ e-barzh"
|
||||||
},
|
},
|
||||||
|
|
@ -32,6 +41,9 @@
|
||||||
"progressWindow_error_translation": {
|
"progressWindow_error_translation": {
|
||||||
"message": "Ur fazi a zo c'hoarvezet en ur enrollañ an elfenn-mañ. Sellit ouzh $1 evit kaout muioc'h a ditouroù."
|
"message": "Ur fazi a zo c'hoarvezet en ur enrollañ an elfenn-mañ. Sellit ouzh $1 evit kaout muioc'h a ditouroù."
|
||||||
},
|
},
|
||||||
|
"progressWindow_error_siteAccessLimitsError": {
|
||||||
|
"message": "Ur fazi a zo c'hoarvezet en ur enrollañ an elfenn-mañ. $1 a c'hall bevenniñ an niver a elfennoù a c'hellit enrollañ war ar memes tro. Sellit ouzh $2 evit kaout muioc'h a ditouroù."
|
||||||
|
},
|
||||||
"progressWindow_error_troubleshootingTranslatorIssues": {
|
"progressWindow_error_troubleshootingTranslatorIssues": {
|
||||||
"message": "Distankañ ar c'hudennoù troidigezh"
|
"message": "Distankañ ar c'hudennoù troidigezh"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<!ENTITY zotero.general.deselectAll "Diziuzañ pep-tra">
|
<!ENTITY zotero.general.deselectAll "Diziuzañ pep-tra">
|
||||||
<!ENTITY zotero.general.edit "Aozañ">
|
<!ENTITY zotero.general.edit "Aozañ">
|
||||||
<!ENTITY zotero.general.delete "Dilemel">
|
<!ENTITY zotero.general.delete "Dilemel">
|
||||||
<!ENTITY zotero.general.moveToTrash "Move to Trash">
|
<!ENTITY zotero.general.moveToTrash "Kas d'ar pod-lastez">
|
||||||
<!ENTITY zotero.general.ok "Mat eo">
|
<!ENTITY zotero.general.ok "Mat eo">
|
||||||
<!ENTITY zotero.general.cancel "Nullañ">
|
<!ENTITY zotero.general.cancel "Nullañ">
|
||||||
<!ENTITY zotero.general.refresh "Freskaat">
|
<!ENTITY zotero.general.refresh "Freskaat">
|
||||||
|
|
@ -45,7 +45,7 @@
|
||||||
<!ENTITY zotero.upgrade.changeLogLink "renabl ar cheñchamantoù">
|
<!ENTITY zotero.upgrade.changeLogLink "renabl ar cheñchamantoù">
|
||||||
<!ENTITY zotero.upgrade.changeLogAfterLink "evit dizoloiñ ar pezh a zo nevez.">
|
<!ENTITY zotero.upgrade.changeLogAfterLink "evit dizoloiñ ar pezh a zo nevez.">
|
||||||
|
|
||||||
<!ENTITY zotero.tabs.info.label "Titou">
|
<!ENTITY zotero.tabs.info.label "Titou.">
|
||||||
<!ENTITY zotero.tabs.notes.label "Notennoù">
|
<!ENTITY zotero.tabs.notes.label "Notennoù">
|
||||||
<!ENTITY zotero.tabs.attachments.label "Pezhioù-stag">
|
<!ENTITY zotero.tabs.attachments.label "Pezhioù-stag">
|
||||||
<!ENTITY zotero.tabs.tags.label "Balizoù">
|
<!ENTITY zotero.tabs.tags.label "Balizoù">
|
||||||
|
|
@ -129,7 +129,7 @@
|
||||||
<!ENTITY zotero.toolbar.attachment.weblink "Enrollañ al liamm d'ar bajenn a-vremañ">
|
<!ENTITY zotero.toolbar.attachment.weblink "Enrollañ al liamm d'ar bajenn a-vremañ">
|
||||||
<!ENTITY zotero.toolbar.attachment.snapshot "Kemer un dapadenn-skramm eus ar bajenn a-vremañ">
|
<!ENTITY zotero.toolbar.attachment.snapshot "Kemer un dapadenn-skramm eus ar bajenn a-vremañ">
|
||||||
<!ENTITY zotero.toolbar.context.item "Elfenn">
|
<!ENTITY zotero.toolbar.context.item "Elfenn">
|
||||||
<!ENTITY zotero.toolbar.context.notes "Notes">
|
<!ENTITY zotero.toolbar.context.notes "Notennoù">
|
||||||
|
|
||||||
<!ENTITY zotero.tagSelector.noTagsToDisplay "Baliz ebet da ziskouez">
|
<!ENTITY zotero.tagSelector.noTagsToDisplay "Baliz ebet da ziskouez">
|
||||||
<!ENTITY zotero.tagSelector.loadingTags "O kargañ ar balizoù...">
|
<!ENTITY zotero.tagSelector.loadingTags "O kargañ ar balizoù...">
|
||||||
|
|
@ -147,7 +147,7 @@
|
||||||
<!ENTITY zotero.tagColorChooser.setColor "Termeniñ al liv">
|
<!ENTITY zotero.tagColorChooser.setColor "Termeniñ al liv">
|
||||||
<!ENTITY zotero.tagColorChooser.removeColor "Dilemel al liv">
|
<!ENTITY zotero.tagColorChooser.removeColor "Dilemel al liv">
|
||||||
|
|
||||||
<!ENTITY zotero.lookup.description "Enter ISBNs, DOIs, PMIDs, arXiv IDs, or ADS Bibcodes to add to your library:">
|
<!ENTITY zotero.lookup.description "Ebarzhiñ anaouadurioù ISBNoù, DOIoù, PMIDs, arXiv pe c'hoazh bibcodes ADS evit gellout ouzhpennañ d'ho levraoueg:">
|
||||||
<!ENTITY zotero.lookup.button.search "Klask">
|
<!ENTITY zotero.lookup.button.search "Klask">
|
||||||
|
|
||||||
<!ENTITY zotero.createParent.title "Krouiñ un elfenn kar">
|
<!ENTITY zotero.createParent.title "Krouiñ un elfenn kar">
|
||||||
|
|
@ -196,7 +196,7 @@
|
||||||
|
|
||||||
<!ENTITY zotero.citation.keepSorted.label "Mirout ar mammennoù rummet">
|
<!ENTITY zotero.citation.keepSorted.label "Mirout ar mammennoù rummet">
|
||||||
|
|
||||||
<!ENTITY zotero.citation.suppressAuthor.label "Omit Author">
|
<!ENTITY zotero.citation.suppressAuthor.label "Lezel a-gostez an Aozer">
|
||||||
<!ENTITY zotero.citation.prefix.label "Rakger:">
|
<!ENTITY zotero.citation.prefix.label "Rakger:">
|
||||||
<!ENTITY zotero.citation.suffix.label "Lostger:">
|
<!ENTITY zotero.citation.suffix.label "Lostger:">
|
||||||
<!ENTITY zotero.citation.editorWarning.label "Kemenn-diwall: Ma aozit un arroudenn en aozer, ne vo ket gouest ken da velezouriñ ar cheñchadurioù en ho tiaz-roadennoù pe ar stil arroudenniñ.">
|
<!ENTITY zotero.citation.editorWarning.label "Kemenn-diwall: Ma aozit un arroudenn en aozer, ne vo ket gouest ken da velezouriñ ar cheñchadurioù en ho tiaz-roadennoù pe ar stil arroudenniñ.">
|
||||||
|
|
@ -307,12 +307,10 @@
|
||||||
<!ENTITY zotero.context.addStandaloneNoteFromAnnotations "Add Standalone Note from Annotations">
|
<!ENTITY zotero.context.addStandaloneNoteFromAnnotations "Add Standalone Note from Annotations">
|
||||||
<!ENTITY zotero.context.editInWindow "Edit in a Separate Window">
|
<!ENTITY zotero.context.editInWindow "Edit in a Separate Window">
|
||||||
|
|
||||||
<!ENTITY zotero.pdfReader.firstPage "First Page">
|
<!ENTITY zotero.pdfReader.firstPage "Pajenn gentañ">
|
||||||
<!ENTITY zotero.pdfReader.lastPage "Last Page">
|
<!ENTITY zotero.pdfReader.lastPage "Last Page">
|
||||||
<!ENTITY zotero.pdfReader.back "Back">
|
<!ENTITY zotero.pdfReader.back "Distreiñ">
|
||||||
<!ENTITY zotero.pdfReader.forward "Forward">
|
<!ENTITY zotero.pdfReader.forward "Forward">
|
||||||
<!ENTITY zotero.pdfReader.rotateClockwise "Rotate Clockwise">
|
|
||||||
<!ENTITY zotero.pdfReader.rotateCounterclockwise "Rotate Counterclockwise">
|
|
||||||
<!ENTITY zotero.pdfReader.handTool "Hand Tool">
|
<!ENTITY zotero.pdfReader.handTool "Hand Tool">
|
||||||
<!ENTITY zotero.pdfReader.verticalScrolling "Vertical Scrolling">
|
<!ENTITY zotero.pdfReader.verticalScrolling "Vertical Scrolling">
|
||||||
<!ENTITY zotero.pdfReader.horizontalScrolling "Horizontal Scrolling">
|
<!ENTITY zotero.pdfReader.horizontalScrolling "Horizontal Scrolling">
|
||||||
|
|
@ -320,9 +318,14 @@
|
||||||
<!ENTITY zotero.pdfReader.noSpreads "No Spreads">
|
<!ENTITY zotero.pdfReader.noSpreads "No Spreads">
|
||||||
<!ENTITY zotero.pdfReader.oddSpreads "Odd Spreads">
|
<!ENTITY zotero.pdfReader.oddSpreads "Odd Spreads">
|
||||||
<!ENTITY zotero.pdfReader.evenSpreads "Even Spreads">
|
<!ENTITY zotero.pdfReader.evenSpreads "Even Spreads">
|
||||||
<!ENTITY zotero.pdfReader.zoomIn "Zoom In">
|
<!ENTITY zotero.pdfReader.zoomIn "Zoumañ">
|
||||||
<!ENTITY zotero.pdfReader.zoomOut "Zoom Out">
|
<!ENTITY zotero.pdfReader.zoomOut "Dizoumañ">
|
||||||
<!ENTITY zotero.pdfReader.zoomAuto "Automatically Resize">
|
<!ENTITY zotero.pdfReader.zoomAuto "Automatically Resize">
|
||||||
<!ENTITY zotero.pdfReader.zoomPageWidth "Zoom to Page Width">
|
<!ENTITY zotero.pdfReader.zoomPageWidth "Zoom to Page Width">
|
||||||
<!ENTITY zotero.pdfReader.zoomPageHeight "Zoom to Page Height">
|
<!ENTITY zotero.pdfReader.zoomPageHeight "Zoom to Page Height">
|
||||||
|
<!ENTITY zotero.pdfReader.splitVertically "Split Vertically">
|
||||||
|
<!ENTITY zotero.pdfReader.splitHorizontally "Split Horizontally">
|
||||||
<!ENTITY zotero.pdfReader.transferFromPDF "Import Annotations…">
|
<!ENTITY zotero.pdfReader.transferFromPDF "Import Annotations…">
|
||||||
|
<!ENTITY zotero.pdfReader.rotatePageLeft "Rotate Page Left">
|
||||||
|
<!ENTITY zotero.pdfReader.rotatePageRight "Rotate Page Right">
|
||||||
|
<!ENTITY zotero.pdfReader.rotatePage180 "Rotate Page 180°">
|
||||||
|
|
|
||||||
|
|
@ -71,9 +71,9 @@ general.fix=Kempenn...
|
||||||
general.tryAgain=Klask en-dro
|
general.tryAgain=Klask en-dro
|
||||||
general.tryLater=Klask diwezhatoc'h
|
general.tryLater=Klask diwezhatoc'h
|
||||||
general.showDirectory=Diskouez ar c'havlec'h
|
general.showDirectory=Diskouez ar c'havlec'h
|
||||||
general.showInLibrary=Show in Library
|
general.showInLibrary=Diskouez el levraoueg:
|
||||||
general.continue=Kenderc'hel
|
general.continue=Kenderc'hel
|
||||||
general.copy=Copy
|
general.copy=Eilañ
|
||||||
general.copyToClipboard=Eilañ er golver
|
general.copyToClipboard=Eilañ er golver
|
||||||
general.cancel=Nullañ
|
general.cancel=Nullañ
|
||||||
general.clear=Diverkañ
|
general.clear=Diverkañ
|
||||||
|
|
@ -88,10 +88,11 @@ general.pdf=PDF
|
||||||
general.back=Distreiñ
|
general.back=Distreiñ
|
||||||
general.languages=Yezhoù
|
general.languages=Yezhoù
|
||||||
general.default=Default
|
general.default=Default
|
||||||
general.custom=Custom
|
general.custom=Personelaet
|
||||||
general.loading=O kargañ...
|
general.loading=O kargañ...
|
||||||
general.richText=Rich Text
|
general.richText=Rich Text
|
||||||
general.clearSelection=Clear Selection
|
general.clearSelection=Clear Selection
|
||||||
|
general.insert=Insert
|
||||||
|
|
||||||
general.yellow=Melen
|
general.yellow=Melen
|
||||||
general.red=Ruz
|
general.red=Ruz
|
||||||
|
|
@ -114,6 +115,7 @@ about.getInvolved=C'hoant ho peus reiñ an dorn? [Kemerit-perzh] bremañ!
|
||||||
punctuation.openingQMark=“
|
punctuation.openingQMark=“
|
||||||
punctuation.closingQMark=”
|
punctuation.closingQMark=”
|
||||||
punctuation.colon=:
|
punctuation.colon=:
|
||||||
|
punctuation.colon.withString=%S:
|
||||||
punctuation.ellipsis=…
|
punctuation.ellipsis=…
|
||||||
|
|
||||||
install.quickStartGuide=Heñcher dillo evit stagañ e-barzh
|
install.quickStartGuide=Heñcher dillo evit stagañ e-barzh
|
||||||
|
|
@ -327,8 +329,11 @@ pane.items.remove.multiple=Ha sur oc'h ho peus c'hoant da zilemel an elfennoù d
|
||||||
pane.items.removeFromPublications.title=Tennañ diwar Ma Embannadennoù
|
pane.items.removeFromPublications.title=Tennañ diwar Ma Embannadennoù
|
||||||
pane.items.removeFromPublications=Ha sur ho peus c'hoant da zilemel an elfenn diuzet diwar Ma Embannadennoù?
|
pane.items.removeFromPublications=Ha sur ho peus c'hoant da zilemel an elfenn diuzet diwar Ma Embannadennoù?
|
||||||
pane.items.removeFromPublications.multiple=Ha sur ho peus c'hoant da zilemel an elfennoù diuzet diwar Ma Embannadennoù?
|
pane.items.removeFromPublications.multiple=Ha sur ho peus c'hoant da zilemel an elfennoù diuzet diwar Ma Embannadennoù?
|
||||||
|
pane.items.removeRecursive.title=Remove from Collection and Subcollections
|
||||||
|
pane.items.removeRecursive=Are you sure you want to remove the selected item from this collection and all subcollections?
|
||||||
|
pane.items.removeRecursive.multiple=Are you sure you want to remove the selected items from this collection and all subcollections?
|
||||||
pane.items.menu.addNoteFromAnnotations=Add Note from Annotations
|
pane.items.menu.addNoteFromAnnotations=Add Note from Annotations
|
||||||
pane.items.menu.addNoteFromAnnotations.multiple=Add Notes from Annotations
|
pane.items.menu.createNoteFromAnnotations=Create Note from Annotations
|
||||||
pane.items.menu.findAvailablePDF=Kavout ur PDF hegerz
|
pane.items.menu.findAvailablePDF=Kavout ur PDF hegerz
|
||||||
pane.items.menu.findAvailablePDF.multiple=Kavout PDFoù hegerz
|
pane.items.menu.findAvailablePDF.multiple=Kavout PDFoù hegerz
|
||||||
pane.items.menu.addToCollection=Add to Collection
|
pane.items.menu.addToCollection=Add to Collection
|
||||||
|
|
@ -338,11 +343,13 @@ pane.items.menu.removeFromPublications=Tennañ an elfenn diwar Ma Embannadennoù
|
||||||
pane.items.menu.removeFromPublications.multiple=Tennañ an elfennoù diwar Ma Embannadennoù...
|
pane.items.menu.removeFromPublications.multiple=Tennañ an elfennoù diwar Ma Embannadennoù...
|
||||||
pane.items.menu.moveToTrash=Kas an elfenn d'ar pod-lastez...
|
pane.items.menu.moveToTrash=Kas an elfenn d'ar pod-lastez...
|
||||||
pane.items.menu.moveToTrash.multiple=Kas an elfennoù d'ar pod-lastez...
|
pane.items.menu.moveToTrash.multiple=Kas an elfennoù d'ar pod-lastez...
|
||||||
pane.items.menu.delete=Delete Permanently…
|
pane.items.menu.delete=Dilemel da virviken...
|
||||||
pane.items.menu.export=Ezporzhiañ an elfenn...
|
pane.items.menu.export=Ezporzhiañ an elfenn...
|
||||||
pane.items.menu.export.multiple=Ezporzhiañ an elfennoù...
|
pane.items.menu.export.multiple=Ezporzhiañ an elfennoù...
|
||||||
pane.items.menu.exportNote=Export Note…
|
pane.items.menu.exportNote=Export Note…
|
||||||
pane.items.menu.exportNote.multiple=Export Notes…
|
pane.items.menu.exportNote.multiple=Export Notes…
|
||||||
|
pane.items.menu.exportPDF=Export PDF…
|
||||||
|
pane.items.menu.exportPDF.multiple=Export PDFs…
|
||||||
pane.items.menu.createBib=Krouiñ ul levrlennadur diwar an elfenn...
|
pane.items.menu.createBib=Krouiñ ul levrlennadur diwar an elfenn...
|
||||||
pane.items.menu.createBib.multiple=Krouiñ ul levrlennadur diwar an elfennoù...
|
pane.items.menu.createBib.multiple=Krouiñ ul levrlennadur diwar an elfennoù...
|
||||||
pane.items.menu.generateReport=Genel un danevell diwar an elfenn...
|
pane.items.menu.generateReport=Genel un danevell diwar an elfenn...
|
||||||
|
|
@ -355,6 +362,8 @@ pane.items.menu.createParent=Krouiñ un elfenn kar...
|
||||||
pane.items.menu.createParent.multiple=Krouiñ elfennoù kar
|
pane.items.menu.createParent.multiple=Krouiñ elfennoù kar
|
||||||
pane.items.menu.renameAttachments=Adenvel ar restr diwar ar meta-roadenn kar
|
pane.items.menu.renameAttachments=Adenvel ar restr diwar ar meta-roadenn kar
|
||||||
pane.items.menu.renameAttachments.multiple=Adenvel ar restroù diwar ar meta-roadenn kar
|
pane.items.menu.renameAttachments.multiple=Adenvel ar restroù diwar ar meta-roadenn kar
|
||||||
|
pane.items.menu.duplicateAndConvert.toBookSection=Create Book Section
|
||||||
|
pane.items.menu.duplicateAndConvert.toBook=Create Book from Book Section
|
||||||
pane.items.showItemInLibrary=Diskouez an elfenn el levraoueg
|
pane.items.showItemInLibrary=Diskouez an elfenn el levraoueg
|
||||||
|
|
||||||
pane.items.letter.oneParticipant=Lizher da %S
|
pane.items.letter.oneParticipant=Lizher da %S
|
||||||
|
|
@ -408,6 +417,16 @@ pane.item.attachments.fileNotFound.text2.stored=Dleout a ra bezañ fiñvet pe di
|
||||||
pane.item.attachments.fileNotFound.text2.stored.notOnServer=Dleout a ra bezañ fiñvet pe dilamet en diavaez eus %1$S, pe, m'eo bet ouzhpennet war un urzhiataer all, posupl eo ne vefe ket bet sinkroet da %2$S.
|
pane.item.attachments.fileNotFound.text2.stored.notOnServer=Dleout a ra bezañ fiñvet pe dilamet en diavaez eus %1$S, pe, m'eo bet ouzhpennet war un urzhiataer all, posupl eo ne vefe ket bet sinkroet da %2$S.
|
||||||
pane.item.attachments.fileNotFound.text2.linked=Dleout a ra bezañ fiñvet pe dilamet er maez eus %1$S, pe ur Stagadenn Kavlec'h Diazez Liammet dleout a ra bezañ diazezet en un doare fall e-diabarzh unan hoc'h urzhiataer.
|
pane.item.attachments.fileNotFound.text2.linked=Dleout a ra bezañ fiñvet pe dilamet er maez eus %1$S, pe ur Stagadenn Kavlec'h Diazez Liammet dleout a ra bezañ diazezet en un doare fall e-diabarzh unan hoc'h urzhiataer.
|
||||||
pane.item.attachments.delete.confirm=Ha fellout a ra deoc'h dilemel da vat ar pezh-stag-mañ?
|
pane.item.attachments.delete.confirm=Ha fellout a ra deoc'h dilemel da vat ar pezh-stag-mañ?
|
||||||
|
pane.item.attachments.autoRelink.title=File Located Automatically
|
||||||
|
pane.item.attachments.autoRelink.text1=The file could not be found at the specified location, but a file with the same name was found within your Linked Attachment Base Directory:
|
||||||
|
pane.item.attachments.autoRelink.text2=Old Location: %S
|
||||||
|
pane.item.attachments.autoRelink.text3=New Location: %S
|
||||||
|
pane.item.attachments.autoRelink.text4=%1$S can automatically relink this attachment.
|
||||||
|
pane.item.attachments.autoRelink.relink=Relink
|
||||||
|
pane.item.attachments.autoRelinkOthers.title=Additional Files Located
|
||||||
|
pane.item.attachments.autoRelinkOthers.text=One other unlinked attachment in this library was found within the same directory. Relink this attachment as well?;%S other unlinked attachments in this library were found within the same directory. Relink all located attachments?
|
||||||
|
pane.item.attachments.autoRelink.locateManually=Locate Manually…
|
||||||
|
pane.item.attachments.autoRelink.relinkAll=Relink All
|
||||||
pane.item.attachments.count.zero=%S a bezhioù-stag:
|
pane.item.attachments.count.zero=%S a bezhioù-stag:
|
||||||
pane.item.attachments.count.singular=%S pezh-stag:
|
pane.item.attachments.count.singular=%S pezh-stag:
|
||||||
pane.item.attachments.count.plural=%S a bezhioù-stag:
|
pane.item.attachments.count.plural=%S a bezhioù-stag:
|
||||||
|
|
@ -430,7 +449,7 @@ pane.item.related.count.zero=%S kevreet:
|
||||||
pane.item.related.count.singular=%S kevreet:
|
pane.item.related.count.singular=%S kevreet:
|
||||||
pane.item.related.count.plural=%S kevreet:
|
pane.item.related.count.plural=%S kevreet:
|
||||||
pane.item.parentItem=Elfenn kar:
|
pane.item.parentItem=Elfenn kar:
|
||||||
pane.item.viewOnline.tooltip=Go to this item online
|
pane.item.viewOnline.tooltip=Mont d'an elfenn-mañ enlinenn
|
||||||
|
|
||||||
pane.context.noParent=Elfenn kar ebet
|
pane.context.noParent=Elfenn kar ebet
|
||||||
pane.context.itemNotes=Item Notes
|
pane.context.itemNotes=Item Notes
|
||||||
|
|
@ -550,7 +569,7 @@ itemFields.audioFileType=Doare restr
|
||||||
itemFields.versionNumber=Stumm
|
itemFields.versionNumber=Stumm
|
||||||
itemFields.system=Sistem
|
itemFields.system=Sistem
|
||||||
itemFields.company=Kumpaniezh
|
itemFields.company=Kumpaniezh
|
||||||
itemFields.conferenceName=Anv prezegenn
|
itemFields.conferenceName=Anv koñferañs
|
||||||
itemFields.encyclopediaTitle=Titl hollouiziegezh
|
itemFields.encyclopediaTitle=Titl hollouiziegezh
|
||||||
itemFields.dictionaryTitle=Titl ar geriadur
|
itemFields.dictionaryTitle=Titl ar geriadur
|
||||||
itemFields.language=Yezh
|
itemFields.language=Yezh
|
||||||
|
|
@ -604,7 +623,7 @@ creatorTypes.scriptwriter=Skriver-skriptoù
|
||||||
creatorTypes.producer=Produer
|
creatorTypes.producer=Produer
|
||||||
creatorTypes.castMember=Ezel ar c'homedianeta
|
creatorTypes.castMember=Ezel ar c'homedianeta
|
||||||
creatorTypes.sponsor=Sponsor
|
creatorTypes.sponsor=Sponsor
|
||||||
creatorTypes.counsel=Kuzul
|
creatorTypes.counsel=Kuzulier
|
||||||
creatorTypes.inventor=Ijiner
|
creatorTypes.inventor=Ijiner
|
||||||
creatorTypes.attorneyAgent=Dileuriad/Ajant
|
creatorTypes.attorneyAgent=Dileuriad/Ajant
|
||||||
creatorTypes.recipient=Resever
|
creatorTypes.recipient=Resever
|
||||||
|
|
@ -619,7 +638,7 @@ creatorTypes.presenter=Kinniger
|
||||||
creatorTypes.guest=Den pedet
|
creatorTypes.guest=Den pedet
|
||||||
creatorTypes.podcaster=Podskigner
|
creatorTypes.podcaster=Podskigner
|
||||||
creatorTypes.reviewedAuthor=Aozer niverennet
|
creatorTypes.reviewedAuthor=Aozer niverennet
|
||||||
creatorTypes.cosponsor=Ken-tad-paeron
|
creatorTypes.cosponsor=Ken-sponsor
|
||||||
creatorTypes.bookAuthor=Aozer al levr
|
creatorTypes.bookAuthor=Aozer al levr
|
||||||
|
|
||||||
fileTypes.webpage=Pajenn web
|
fileTypes.webpage=Pajenn web
|
||||||
|
|
@ -719,6 +738,7 @@ zotero.preferences.export.quickCopy.citationStyles=Doare arroudenn
|
||||||
zotero.preferences.export.quickCopy.exportFormats=Ezporzhiañ ar stummoù
|
zotero.preferences.export.quickCopy.exportFormats=Ezporzhiañ ar stummoù
|
||||||
zotero.preferences.export.quickCopy.instructions=An Eilañ prim a ro an tu deoc'h da ezporzhiañ buan-tre an elfennoù en ur stumm roet. Gellout a rit eilañ an elfennoù diuzet er golver en ur bouezañ war %S pe rinklit an elfennoù war-eeun e-barzh ur voest testenn e-barzh ur program all.
|
zotero.preferences.export.quickCopy.instructions=An Eilañ prim a ro an tu deoc'h da ezporzhiañ buan-tre an elfennoù en ur stumm roet. Gellout a rit eilañ an elfennoù diuzet er golver en ur bouezañ war %S pe rinklit an elfennoù war-eeun e-barzh ur voest testenn e-barzh ur program all.
|
||||||
zotero.preferences.export.quickCopy.citationInstructions=Evit ar stiloù arroudenn e c'hallit eilañ an arroudennoù pe an notennoù-traoñ pajenn en ur bouezañ war %S pe en ur zerc'hel war Linkad a-raok rinklañ-stlejañ elfennoù.
|
zotero.preferences.export.quickCopy.citationInstructions=Evit ar stiloù arroudenn e c'hallit eilañ an arroudennoù pe an notennoù-traoñ pajenn en ur bouezañ war %S pe en ur zerc'hel war Linkad a-raok rinklañ-stlejañ elfennoù.
|
||||||
|
zotero.preferences.export.quickCopy.note.htmlOptions.label=Rich Text/HTML
|
||||||
|
|
||||||
zotero.preferences.wordProcessors.installationSuccess=Berzh en deus graet ar staliadur.
|
zotero.preferences.wordProcessors.installationSuccess=Berzh en deus graet ar staliadur.
|
||||||
zotero.preferences.wordProcessors.installationError=N'hall ket bezañ klokaet ar staliadur rak ur fazi a zo c'hoarvezet. Bezit asur eo sarr %1$S, hag adloc'hit goude-se %2$S.
|
zotero.preferences.wordProcessors.installationError=N'hall ket bezañ klokaet ar staliadur rak ur fazi a zo c'hoarvezet. Bezit asur eo sarr %1$S, hag adloc'hit goude-se %2$S.
|
||||||
|
|
@ -864,22 +884,7 @@ citation.showEditor=Diskouez an aozer...
|
||||||
citation.hideEditor=Kuzhat an aozer...
|
citation.hideEditor=Kuzhat an aozer...
|
||||||
citation.citations=Arroudennoù
|
citation.citations=Arroudennoù
|
||||||
citation.notes=Notennoù
|
citation.notes=Notennoù
|
||||||
citation.locator.page=Pajenn
|
citation.locator.timestamp=Timestamp
|
||||||
citation.locator.book=Levr
|
|
||||||
citation.locator.chapter=Chabistr
|
|
||||||
citation.locator.column=Bann
|
|
||||||
citation.locator.figure=Lun
|
|
||||||
citation.locator.folio=Folio
|
|
||||||
citation.locator.issue=Niverenn
|
|
||||||
citation.locator.line=Linenn
|
|
||||||
citation.locator.note=Notenn
|
|
||||||
citation.locator.opus=Opus
|
|
||||||
citation.locator.paragraph=Rannbennad
|
|
||||||
citation.locator.part=Lodenn
|
|
||||||
citation.locator.section=Kevrenn
|
|
||||||
citation.locator.subverbo=Sub verbo
|
|
||||||
citation.locator.volume=Levrenn
|
|
||||||
citation.locator.verse=Gwerzad
|
|
||||||
|
|
||||||
report.title.default=Danevell Zotero
|
report.title.default=Danevell Zotero
|
||||||
report.parentItem=Elfenn kar:
|
report.parentItem=Elfenn kar:
|
||||||
|
|
@ -1005,7 +1010,7 @@ sync.skipGroup=Tremen ar strollad
|
||||||
sync.removeGroupsAndSync=Tennañ ar strolladoù ha sinkro
|
sync.removeGroupsAndSync=Tennañ ar strolladoù ha sinkro
|
||||||
|
|
||||||
sync.reminder.setUp.message=Back up your library with %S syncing.
|
sync.reminder.setUp.message=Back up your library with %S syncing.
|
||||||
sync.reminder.setUp.action=Set Up Syncing
|
sync.reminder.setUp.action=Termeniñ ar sinkro
|
||||||
sync.reminder.autoSync.message=%S hasn’t synced in a while. Do you want to enable automatic syncing?
|
sync.reminder.autoSync.message=%S hasn’t synced in a while. Do you want to enable automatic syncing?
|
||||||
|
|
||||||
sync.error.usernameNotSet=Anv-implijer didermenet:
|
sync.error.usernameNotSet=Anv-implijer didermenet:
|
||||||
|
|
@ -1210,7 +1215,7 @@ lookup.failureTooMany.description=Re a anaouadurioù. Ebarzhit un anaouader mar
|
||||||
createParent.prompt=Enter a DOI, ISBN, PMID, arXiv ID, or ADS Bibcode to identify this file
|
createParent.prompt=Enter a DOI, ISBN, PMID, arXiv ID, or ADS Bibcode to identify this file
|
||||||
|
|
||||||
locate.online.label=Diskouez enlinenn
|
locate.online.label=Diskouez enlinenn
|
||||||
locate.pdf.label=Open PDF
|
locate.pdf.label=Digeriñ ar PDF
|
||||||
locate.pdfNewWindow.label=Open PDF in New Window
|
locate.pdfNewWindow.label=Open PDF in New Window
|
||||||
locate.snapshot.label=Diskouez an dapadenn
|
locate.snapshot.label=Diskouez an dapadenn
|
||||||
locate.file.label=Diskouez ar restr
|
locate.file.label=Diskouez ar restr
|
||||||
|
|
@ -1218,6 +1223,8 @@ locate.externalViewer.label=Digeriñ gant ul lenner diavaez
|
||||||
locate.internalViewer.label=Digeriñ e-barzh ul lenner diabarzh
|
locate.internalViewer.label=Digeriñ e-barzh ul lenner diabarzh
|
||||||
locate.showFile.label=Diskouez ar restr
|
locate.showFile.label=Diskouez ar restr
|
||||||
locate.libraryLookup.label=Klask el levraoueg
|
locate.libraryLookup.label=Klask el levraoueg
|
||||||
|
locate.libraryLookup.noResolver.title=No OpenURL Resolver
|
||||||
|
locate.libraryLookup.noResolver.text=You must choose an OpenURL resolver from the Advanced pane of the %S preferences.
|
||||||
locate.manageLocateEngines=Merañ al luskerioù enklask...
|
locate.manageLocateEngines=Merañ al luskerioù enklask...
|
||||||
locate.locateEngineDescription=Lookup engines help you find resources in your %S library on the web. Engines enabled in this list appear in the Locate drop-down in the toolbar.
|
locate.locateEngineDescription=Lookup engines help you find resources in your %S library on the web. Engines enabled in this list appear in the Locate drop-down in the toolbar.
|
||||||
|
|
||||||
|
|
@ -1308,15 +1315,16 @@ noteEditor.monospaced=Monospaced
|
||||||
noteEditor.bulletList=Bulleted List
|
noteEditor.bulletList=Bulleted List
|
||||||
noteEditor.orderedList=Numbered List
|
noteEditor.orderedList=Numbered List
|
||||||
noteEditor.blockquote=Block Quote
|
noteEditor.blockquote=Block Quote
|
||||||
|
noteEditor.mathBlock=Math Block
|
||||||
noteEditor.formatText=Format Text
|
noteEditor.formatText=Format Text
|
||||||
noteEditor.highlightText=Highlight Text
|
noteEditor.highlightText=Usskediñ an destenn
|
||||||
noteEditor.removeColor=Remove Color
|
noteEditor.removeColor=Dilemel al liv
|
||||||
noteEditor.bold=Bold
|
noteEditor.bold=Druz
|
||||||
noteEditor.italic=Italic
|
noteEditor.italic=Stouet
|
||||||
noteEditor.underline=Islinennet
|
noteEditor.underline=Islinennet
|
||||||
noteEditor.strikethrough=Strikethrough
|
noteEditor.strikethrough=Strikethrough
|
||||||
noteEditor.subscript=Subscript
|
noteEditor.subscript=Isskrid
|
||||||
noteEditor.superscript=Superscript
|
noteEditor.superscript=Usskrid
|
||||||
noteEditor.returnToNotesList=Return to Notes List
|
noteEditor.returnToNotesList=Return to Notes List
|
||||||
noteEditor.insertLink=Insert Link
|
noteEditor.insertLink=Insert Link
|
||||||
noteEditor.clearFormatting=Clear Formatting
|
noteEditor.clearFormatting=Clear Formatting
|
||||||
|
|
@ -1327,7 +1335,7 @@ noteEditor.alignRight=Align Right
|
||||||
noteEditor.insertCitation=Insert Citation
|
noteEditor.insertCitation=Insert Citation
|
||||||
noteEditor.more=Muioc'h
|
noteEditor.more=Muioc'h
|
||||||
noteEditor.find=Find
|
noteEditor.find=Find
|
||||||
noteEditor.replace=Replace
|
noteEditor.replace=Erlec'hiañ
|
||||||
noteEditor.previous=Previous
|
noteEditor.previous=Previous
|
||||||
noteEditor.next=Da-heul
|
noteEditor.next=Da-heul
|
||||||
noteEditor.replaceNext=Erlec'hiañ
|
noteEditor.replaceNext=Erlec'hiañ
|
||||||
|
|
@ -1347,7 +1355,11 @@ noteEditor.applyAnnotationColors=Show Annotation Colors
|
||||||
noteEditor.removeAnnotationColors=Hide Annotation Colors
|
noteEditor.removeAnnotationColors=Hide Annotation Colors
|
||||||
noteEditor.addCitations=Show Annotation Citations
|
noteEditor.addCitations=Show Annotation Citations
|
||||||
noteEditor.removeCitations=Hide Annotation Citations
|
noteEditor.removeCitations=Hide Annotation Citations
|
||||||
noteEditor.insertTable=Insert Table
|
noteEditor.image=Skeudenn
|
||||||
|
noteEditor.math=Math
|
||||||
|
noteEditor.table=Table
|
||||||
|
noteEditor.copyImage=Copy Image
|
||||||
|
noteEditor.saveImageAs=Save Image As…
|
||||||
noteEditor.insertRowBefore=Insert Row Above
|
noteEditor.insertRowBefore=Insert Row Above
|
||||||
noteEditor.insertRowAfter=Insert Row Below
|
noteEditor.insertRowAfter=Insert Row Below
|
||||||
noteEditor.insertColumnBefore=Insert Column Left
|
noteEditor.insertColumnBefore=Insert Column Left
|
||||||
|
|
@ -1360,10 +1372,10 @@ pdfReader.annotations=Ennotadurioù
|
||||||
pdfReader.showAnnotations=Show Annotations
|
pdfReader.showAnnotations=Show Annotations
|
||||||
pdfReader.searchAnnotations=Search Annotations
|
pdfReader.searchAnnotations=Search Annotations
|
||||||
pdfReader.noAnnotations=Create an annotation to see it in the sidebar
|
pdfReader.noAnnotations=Create an annotation to see it in the sidebar
|
||||||
pdfReader.addText=Add extracted text
|
pdfReader.noExtractedText=No extracted text
|
||||||
pdfReader.addComment=Add comment
|
pdfReader.addComment=Add comment
|
||||||
pdfReader.addTags=Add tags…
|
pdfReader.addTags=Add tags…
|
||||||
pdfReader.highlightText=Highlight Text
|
pdfReader.highlightText=Usskediñ an destenn
|
||||||
pdfReader.addNote=Ouzhpennañ un notenn
|
pdfReader.addNote=Ouzhpennañ un notenn
|
||||||
pdfReader.selectArea=Select Area
|
pdfReader.selectArea=Select Area
|
||||||
pdfReader.pickColor=Pick a Color
|
pdfReader.pickColor=Pick a Color
|
||||||
|
|
@ -1373,17 +1385,26 @@ pdfReader.zoomOut=Dizoumañ
|
||||||
pdfReader.zoomAuto=Automatically Resize
|
pdfReader.zoomAuto=Automatically Resize
|
||||||
pdfReader.zoomPageWidth=Zoom to Page Width
|
pdfReader.zoomPageWidth=Zoom to Page Width
|
||||||
pdfReader.zoomPageHeight=Zoom to Page Height
|
pdfReader.zoomPageHeight=Zoom to Page Height
|
||||||
|
pdfReader.splitVertically=Split Vertically
|
||||||
|
pdfReader.splitHorizontally=Split Horizontally
|
||||||
pdfReader.nextPage=Pajenn da-heul
|
pdfReader.nextPage=Pajenn da-heul
|
||||||
pdfReader.previousPage=Previous Page
|
pdfReader.previousPage=Previous Page
|
||||||
pdfReader.page=Page
|
pdfReader.page=Pajenn
|
||||||
pdfReader.readOnly=Read-only
|
pdfReader.readOnly=Read-only
|
||||||
pdfReader.promptTransferFromPDF.title=Import Annotations
|
pdfReader.promptTransferFromPDF.title=Import Annotations
|
||||||
pdfReader.promptTransferFromPDF.text=Annotations stored in the PDF file will be moved to %1$S.
|
pdfReader.promptTransferFromPDF.text=Annotations stored in the PDF file will be moved to %1$S.
|
||||||
pdfReader.promptTransferToPDF.title=Store Annotations in File
|
pdfReader.promptTransferToPDF.title=Store Annotations in File
|
||||||
pdfReader.promptTransferToPDF.text=Annotations will be transferred to the PDF file and will no longer be editable in %S.
|
pdfReader.promptTransferToPDF.text=Annotations will be transferred to the PDF file and will no longer be editable in %S.
|
||||||
pdfReader.promptPasswordProtected=The operation is not supported for password-protected PDF files.
|
pdfReader.promptPasswordProtected=The operation is not supported for password-protected PDF files.
|
||||||
|
pdfReader.promptDeletePages.title=Delete Pages
|
||||||
|
pdfReader.promptDeletePages.text=Are you sure you want to delete %1$S page from the PDF file?;Are you sure you want to delete %1$S pages from the PDF file?
|
||||||
|
pdfReader.rotateLeft=Rotate Left
|
||||||
|
pdfReader.rotateRight=Rotate Right
|
||||||
|
pdfReader.rotate180=Rotate 180°
|
||||||
pdfReader.editPageNumber=Edit Page Number…
|
pdfReader.editPageNumber=Edit Page Number…
|
||||||
pdfReader.editHighlightedText=Edit Highlighted Text
|
pdfReader.editHighlightedText=Edit Highlighted Text
|
||||||
|
pdfReader.copyImage=Copy Image
|
||||||
|
pdfReader.saveImageAs=Save Image As…
|
||||||
pdfReader.pageNumberPopupHeader=Change page number for:
|
pdfReader.pageNumberPopupHeader=Change page number for:
|
||||||
pdfReader.thisAnnotation=This annotation
|
pdfReader.thisAnnotation=This annotation
|
||||||
pdfReader.selectedAnnotations=Selected annotations
|
pdfReader.selectedAnnotations=Selected annotations
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,18 @@
|
||||||
"general_moreInfo": {
|
"general_moreInfo": {
|
||||||
"message": "Més informació…"
|
"message": "Més informació…"
|
||||||
},
|
},
|
||||||
|
"general_needHelp": {
|
||||||
|
"message": "Us cal ajuda?"
|
||||||
|
},
|
||||||
"general_done": {
|
"general_done": {
|
||||||
"message": "Fet"
|
"message": "Fet"
|
||||||
},
|
},
|
||||||
|
"general_yes": {
|
||||||
|
"message": "Sí"
|
||||||
|
},
|
||||||
|
"general_no": {
|
||||||
|
"message": "No"
|
||||||
|
},
|
||||||
"general_tryAgain": {
|
"general_tryAgain": {
|
||||||
"message": "Torna-ho a provar"
|
"message": "Torna-ho a provar"
|
||||||
},
|
},
|
||||||
|
|
@ -32,9 +41,15 @@
|
||||||
"progressWindow_error_translation": {
|
"progressWindow_error_translation": {
|
||||||
"message": "S'ha produït un error desar l'element. Vegeu $1 per a més informació. "
|
"message": "S'ha produït un error desar l'element. Vegeu $1 per a més informació. "
|
||||||
},
|
},
|
||||||
|
"progressWindow_error_siteAccessLimitsError": {
|
||||||
|
"message": "S'ha produït un error en desar l'element. $1 pot limitar el nombre d'elements que podeu desar cada vegada. Vegeu $2 per a més informació."
|
||||||
|
},
|
||||||
"progressWindow_error_troubleshootingTranslatorIssues": {
|
"progressWindow_error_troubleshootingTranslatorIssues": {
|
||||||
"message": "Resolució d'incidències dels tradutors"
|
"message": "Resolució d'incidències dels tradutors"
|
||||||
},
|
},
|
||||||
|
"progressWindow_error_siteAccessLimits": {
|
||||||
|
"message": "Límits d'accés al lloc"
|
||||||
|
},
|
||||||
"progressWindow_error_fallback": {
|
"progressWindow_error_fallback": {
|
||||||
"message": "S'ha produït un error desant $1. Es provarà de desar-ho fent servir $2."
|
"message": "S'ha produït un error desant $1. Es provarà de desar-ho fent servir $2."
|
||||||
},
|
},
|
||||||
|
|
@ -50,6 +65,18 @@
|
||||||
"upgradeApp": {
|
"upgradeApp": {
|
||||||
"message": "Actualitza $1"
|
"message": "Actualitza $1"
|
||||||
},
|
},
|
||||||
|
"firstRun_title": {
|
||||||
|
"message": "Heu instal·lat el connector de $1!"
|
||||||
|
},
|
||||||
|
"firstRun_text1": {
|
||||||
|
"message": "El connector de $1 us permet <a href=\"$2\">desar elements al $1</a> des del vostre navegador amb un sol clic."
|
||||||
|
},
|
||||||
|
"firstRun_text2": {
|
||||||
|
"message": "Si no ho heu fet encara, <a href=\"$2\">baixeu</a> la versió d'escriptori del $1 per a gaudir d'una millor experiència."
|
||||||
|
},
|
||||||
|
"firstRun_acceptButton": {
|
||||||
|
"message": "Entesos"
|
||||||
|
},
|
||||||
"error_connection_isAppRunning": {
|
"error_connection_isAppRunning": {
|
||||||
"message": "Està executant-se el $1?"
|
"message": "Està executant-se el $1?"
|
||||||
},
|
},
|
||||||
|
|
@ -92,6 +119,15 @@
|
||||||
"integration_googleDocs_docxAlert": {
|
"integration_googleDocs_docxAlert": {
|
||||||
"message": "La integració de $1 no és disponible quan s'editen fitxers .docx de Microsoft Word directament a Google Docs. Trieu Fitxer → Desa com a Google Docs per a habilitar aquesta funcionalitat. <br/><br/>Si voleu transferir un document de Word amb citacions de $1 a Google Docs, consulteu <a href=\"https://www.zotero.org/support/kb/moving_documents_between_word_processors\">Moure documents entre processadors de text</a>."
|
"message": "La integració de $1 no és disponible quan s'editen fitxers .docx de Microsoft Word directament a Google Docs. Trieu Fitxer → Desa com a Google Docs per a habilitar aquesta funcionalitat. <br/><br/>Si voleu transferir un document de Word amb citacions de $1 a Google Docs, consulteu <a href=\"https://www.zotero.org/support/kb/moving_documents_between_word_processors\">Moure documents entre processadors de text</a>."
|
||||||
},
|
},
|
||||||
|
"integration_googleDocs_documentLocked": {
|
||||||
|
"message": "Les cites del document estan sent editades per un altre usuari del $1. Torneu-ho a provar més endavant."
|
||||||
|
},
|
||||||
|
"integration_googleDocs_documentLocked_moreInfo": {
|
||||||
|
"message": "El $1 bloqueja el vostre document per a evitar que diferents usuaris puguin editar-hi cites al mateix moment. L'edició concurrent de cites en un mateix document pot portar a la seva corrupció. Circumstàncies no esperades, com ara problemes de xarxa, poden provocar que el document quedi bloquejat de forma permanent. Si creieu que ha passat això, podeu sobreescriure el bloqueig. <br/><br/>Voleu sobreescriure el bloqueig del document?"
|
||||||
|
},
|
||||||
|
"integration_googleDocs_documentPermissionError": {
|
||||||
|
"message": "El compte de Google que heu seleccionat no té permisos per a editar el document. Torneu-ho a provar i assegureu-vos que trieu el compte amb accessos d'edició."
|
||||||
|
},
|
||||||
"integration_googleDocs_orphanedCitations_buttonTooltip": {
|
"integration_googleDocs_orphanedCitations_buttonTooltip": {
|
||||||
"message": "Mostra cites de $1 no enllaçades"
|
"message": "Mostra cites de $1 no enllaçades"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
<!ENTITY zotero.preferences.groups.whenCopyingInclude "Quan copiïs elements entre les biblioteques, inclou-hi:">
|
<!ENTITY zotero.preferences.groups.whenCopyingInclude "Quan copiïs elements entre les biblioteques, inclou-hi:">
|
||||||
<!ENTITY zotero.preferences.groups.childNotes "notes descendents">
|
<!ENTITY zotero.preferences.groups.childNotes "notes descendents">
|
||||||
<!ENTITY zotero.preferences.groups.childFiles "instantànies descendents i fitxers importats">
|
<!ENTITY zotero.preferences.groups.childFiles "instantànies descendents i fitxers importats">
|
||||||
<!ENTITY zotero.preferences.groups.annotations "annotations">
|
<!ENTITY zotero.preferences.groups.annotations "anotacions">
|
||||||
<!ENTITY zotero.preferences.groups.childLinks "enllaços descendents">
|
<!ENTITY zotero.preferences.groups.childLinks "enllaços descendents">
|
||||||
<!ENTITY zotero.preferences.groups.tags "etiquetes">
|
<!ENTITY zotero.preferences.groups.tags "etiquetes">
|
||||||
|
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
<!ENTITY zotero.preferences.feeds.sorting.oldest "Els elements més antics primer">
|
<!ENTITY zotero.preferences.feeds.sorting.oldest "Els elements més antics primer">
|
||||||
<!ENTITY zotero.preferences.feeds.feedDefaults "Paràmetres per defecte dels canals">
|
<!ENTITY zotero.preferences.feeds.feedDefaults "Paràmetres per defecte dels canals">
|
||||||
|
|
||||||
<!ENTITY zotero.preferences.openurl.choose "Choose a resolver…">
|
<!ENTITY zotero.preferences.openurl.choose "Trieu un resolutor:">
|
||||||
<!ENTITY zotero.preferences.openurl.custom "Personalitza…">
|
<!ENTITY zotero.preferences.openurl.custom "Personalitza…">
|
||||||
<!ENTITY zotero.preferences.openurl.server "Resolutor:">
|
<!ENTITY zotero.preferences.openurl.server "Resolutor:">
|
||||||
<!ENTITY zotero.preferences.openurl.version "Versió:">
|
<!ENTITY zotero.preferences.openurl.version "Versió:">
|
||||||
|
|
@ -96,7 +96,7 @@
|
||||||
<!ENTITY zotero.preferences.search.indexStats.words "Paraules:">
|
<!ENTITY zotero.preferences.search.indexStats.words "Paraules:">
|
||||||
|
|
||||||
<!ENTITY zotero.preferences.fulltext.textMaxLength "Nombre màxim de caràcters indexats per fitxer:">
|
<!ENTITY zotero.preferences.fulltext.textMaxLength "Nombre màxim de caràcters indexats per fitxer:">
|
||||||
<!ENTITY zotero.preferences.fulltext.pdfMaxPages "Nombe màxim de pàgines indexades per fitxer:">
|
<!ENTITY zotero.preferences.fulltext.pdfMaxPages "Nombre màxim de pàgines indexades per fitxer:">
|
||||||
|
|
||||||
<!ENTITY zotero.preferences.prefpane.export "Exporta">
|
<!ENTITY zotero.preferences.prefpane.export "Exporta">
|
||||||
|
|
||||||
|
|
@ -105,8 +105,8 @@
|
||||||
<!ENTITY zotero.preferences.export.citePaperJournalArticleURL.description "Quan aquesta opció està deshabilitada, el Zotero inclou les URL quan se citen articles de premsa, revistes i revistes acadèmiques només si l'article no té un ran dge pàgines assignat.">
|
<!ENTITY zotero.preferences.export.citePaperJournalArticleURL.description "Quan aquesta opció està deshabilitada, el Zotero inclou les URL quan se citen articles de premsa, revistes i revistes acadèmiques només si l'article no té un ran dge pàgines assignat.">
|
||||||
|
|
||||||
<!ENTITY zotero.preferences.quickCopy.caption "Còpia ràpida">
|
<!ENTITY zotero.preferences.quickCopy.caption "Còpia ràpida">
|
||||||
<!ENTITY zotero.preferences.quickCopy.itemFormat "Item Format:">
|
<!ENTITY zotero.preferences.quickCopy.itemFormat "Format d'element:">
|
||||||
<!ENTITY zotero.preferences.quickCopy.noteFormat "Note Format:">
|
<!ENTITY zotero.preferences.quickCopy.noteFormat "Format de nota:">
|
||||||
<!ENTITY zotero.preferences.quickCopy.copyAsHTML "Copia com a HTML">
|
<!ENTITY zotero.preferences.quickCopy.copyAsHTML "Copia com a HTML">
|
||||||
<!ENTITY zotero.preferences.quickCopy.siteEditor.setings "Configuració específica per a llocs web:">
|
<!ENTITY zotero.preferences.quickCopy.siteEditor.setings "Configuració específica per a llocs web:">
|
||||||
<!ENTITY zotero.preferences.quickCopy.siteEditor.domainPath "Domini/Ruta">
|
<!ENTITY zotero.preferences.quickCopy.siteEditor.domainPath "Domini/Ruta">
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
<!ENTITY copyCitationCmd.label "Copia la cita">
|
<!ENTITY copyCitationCmd.label "Copia la cita">
|
||||||
<!ENTITY copyBibliographyCmd.label "Copia la bibliografia">
|
<!ENTITY copyBibliographyCmd.label "Copia la bibliografia">
|
||||||
<!ENTITY copyNoteCmd.label "Copy Note">
|
<!ENTITY copyNoteCmd.label "Copia la nota">
|
||||||
|
|
||||||
<!ENTITY bidiSwitchPageDirectionItem.label "Canvia la direcció de la pàgina">
|
<!ENTITY bidiSwitchPageDirectionItem.label "Canvia la direcció de la pàgina">
|
||||||
<!ENTITY bidiSwitchPageDirectionItem.accesskey "g">
|
<!ENTITY bidiSwitchPageDirectionItem.accesskey "g">
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,7 @@
|
||||||
<!ENTITY zotero.tagColorChooser.setColor "Estableix el color">
|
<!ENTITY zotero.tagColorChooser.setColor "Estableix el color">
|
||||||
<!ENTITY zotero.tagColorChooser.removeColor "Elimina el color">
|
<!ENTITY zotero.tagColorChooser.removeColor "Elimina el color">
|
||||||
|
|
||||||
<!ENTITY zotero.lookup.description "Enter ISBNs, DOIs, PMIDs, arXiv IDs, or ADS Bibcodes to add to your library:">
|
<!ENTITY zotero.lookup.description "Introduïu codis ISBN, DOI, PMID, arXiv ID o ADS Bibcodes per afegir a la vostra biblioteca:">
|
||||||
<!ENTITY zotero.lookup.button.search "Cerca">
|
<!ENTITY zotero.lookup.button.search "Cerca">
|
||||||
|
|
||||||
<!ENTITY zotero.createParent.title "Crea un element pare">
|
<!ENTITY zotero.createParent.title "Crea un element pare">
|
||||||
|
|
@ -196,7 +196,7 @@
|
||||||
|
|
||||||
<!ENTITY zotero.citation.keepSorted.label "Mantingues les fonts ordenades">
|
<!ENTITY zotero.citation.keepSorted.label "Mantingues les fonts ordenades">
|
||||||
|
|
||||||
<!ENTITY zotero.citation.suppressAuthor.label "Omit Author">
|
<!ENTITY zotero.citation.suppressAuthor.label "Omet l'autor">
|
||||||
<!ENTITY zotero.citation.prefix.label "Prefix:">
|
<!ENTITY zotero.citation.prefix.label "Prefix:">
|
||||||
<!ENTITY zotero.citation.suffix.label "Sufix:">
|
<!ENTITY zotero.citation.suffix.label "Sufix:">
|
||||||
<!ENTITY zotero.citation.editorWarning.label "Avís: Si editeu la cita a l'editor de cites no s'actualitzarà més i no reflectirà els canvis en la base de dades o de l'estil de cita.">
|
<!ENTITY zotero.citation.editorWarning.label "Avís: Si editeu la cita a l'editor de cites no s'actualitzarà més i no reflectirà els canvis en la base de dades o de l'estil de cita.">
|
||||||
|
|
@ -311,18 +311,21 @@
|
||||||
<!ENTITY zotero.pdfReader.lastPage "Darrera pàgina">
|
<!ENTITY zotero.pdfReader.lastPage "Darrera pàgina">
|
||||||
<!ENTITY zotero.pdfReader.back "Enrere">
|
<!ENTITY zotero.pdfReader.back "Enrere">
|
||||||
<!ENTITY zotero.pdfReader.forward "Endavant">
|
<!ENTITY zotero.pdfReader.forward "Endavant">
|
||||||
<!ENTITY zotero.pdfReader.rotateClockwise "Gira en les agulles del rellotge">
|
|
||||||
<!ENTITY zotero.pdfReader.rotateCounterclockwise "Gira al revés de les agulles del rellotge">
|
|
||||||
<!ENTITY zotero.pdfReader.handTool "Eina de mà">
|
<!ENTITY zotero.pdfReader.handTool "Eina de mà">
|
||||||
<!ENTITY zotero.pdfReader.verticalScrolling "Desplaçament vertical">
|
<!ENTITY zotero.pdfReader.verticalScrolling "Desplaçament vertical">
|
||||||
<!ENTITY zotero.pdfReader.horizontalScrolling "Desplaçament horitzontal">
|
<!ENTITY zotero.pdfReader.horizontalScrolling "Desplaçament horitzontal">
|
||||||
<!ENTITY zotero.pdfReader.wrappedScrolling "Wrapped Scrolling">
|
<!ENTITY zotero.pdfReader.wrappedScrolling "Desplaçament ajustat">
|
||||||
<!ENTITY zotero.pdfReader.noSpreads "No Spreads">
|
<!ENTITY zotero.pdfReader.noSpreads "Cap disposició">
|
||||||
<!ENTITY zotero.pdfReader.oddSpreads "Odd Spreads">
|
<!ENTITY zotero.pdfReader.oddSpreads "Disposició en senars">
|
||||||
<!ENTITY zotero.pdfReader.evenSpreads "Even Spreads">
|
<!ENTITY zotero.pdfReader.evenSpreads "Disposició en parells">
|
||||||
<!ENTITY zotero.pdfReader.zoomIn "Zoom In">
|
<!ENTITY zotero.pdfReader.zoomIn "Amplia">
|
||||||
<!ENTITY zotero.pdfReader.zoomOut "Zoom Out">
|
<!ENTITY zotero.pdfReader.zoomOut "Redueix">
|
||||||
<!ENTITY zotero.pdfReader.zoomAuto "Automatically Resize">
|
<!ENTITY zotero.pdfReader.zoomAuto "Redimensiona automàticament">
|
||||||
<!ENTITY zotero.pdfReader.zoomPageWidth "Zoom to Page Width">
|
<!ENTITY zotero.pdfReader.zoomPageWidth "Ajusta a l'amplada de la pàgina">
|
||||||
<!ENTITY zotero.pdfReader.zoomPageHeight "Zoom to Page Height">
|
<!ENTITY zotero.pdfReader.zoomPageHeight "Ajusta a l'alçada de la pàgina">
|
||||||
<!ENTITY zotero.pdfReader.transferFromPDF "Import Annotations…">
|
<!ENTITY zotero.pdfReader.splitVertically "Divideix verticalment">
|
||||||
|
<!ENTITY zotero.pdfReader.splitHorizontally "Divideix horitzontalment">
|
||||||
|
<!ENTITY zotero.pdfReader.transferFromPDF "Importa anotacions…">
|
||||||
|
<!ENTITY zotero.pdfReader.rotatePageLeft "Rotate Page Left">
|
||||||
|
<!ENTITY zotero.pdfReader.rotatePageRight "Rotate Page Right">
|
||||||
|
<!ENTITY zotero.pdfReader.rotatePage180 "Rotate Page 180°">
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,8 @@ general.checkForUpdates=Comprova si hi ha actualitzacions
|
||||||
general.actionCannotBeUndone=Aquesta acció no es pot desfer.
|
general.actionCannotBeUndone=Aquesta acció no es pot desfer.
|
||||||
general.install=Instal·la
|
general.install=Instal·la
|
||||||
general.updateAvailable=Hi ha una actualització disponible
|
general.updateAvailable=Hi ha una actualització disponible
|
||||||
general.downloading=Downloading %S…
|
general.downloading=S'està baixant %S…
|
||||||
general.downloading.quoted=Downloading “%S”…
|
general.downloading.quoted=S'està baixant «%S»…
|
||||||
general.noUpdatesFound=No s'han trobat actualitzacions
|
general.noUpdatesFound=No s'han trobat actualitzacions
|
||||||
general.isUpToDate=%S està actualitzat.
|
general.isUpToDate=%S està actualitzat.
|
||||||
general.upgrade=Actualitza
|
general.upgrade=Actualitza
|
||||||
|
|
@ -47,12 +47,12 @@ general.delete=Suprimeix
|
||||||
general.remove=Elimina
|
general.remove=Elimina
|
||||||
general.import=Importa
|
general.import=Importa
|
||||||
general.export=Exporta
|
general.export=Exporta
|
||||||
general.update=Update
|
general.update=Actualitza
|
||||||
general.moreInformation=Més informació
|
general.moreInformation=Més informació
|
||||||
general.learnMore=Learn More
|
general.learnMore=Més informació
|
||||||
general.seeForMoreInformation=Mira %S per a més informació.
|
general.seeForMoreInformation=Mira %S per a més informació.
|
||||||
general.open=Obre %S
|
general.open=Obre %S
|
||||||
general.close=Close
|
general.close=Tanca
|
||||||
general.enable=Habilita
|
general.enable=Habilita
|
||||||
general.disable=Deshabilita
|
general.disable=Deshabilita
|
||||||
general.reset=Reinicia
|
general.reset=Reinicia
|
||||||
|
|
@ -65,13 +65,13 @@ general.openPreferences=Obre les preferències
|
||||||
general.keys.ctrlShift=Ctrl+Shift+
|
general.keys.ctrlShift=Ctrl+Shift+
|
||||||
general.keys.cmdShift=Cmd+Shift+
|
general.keys.cmdShift=Cmd+Shift+
|
||||||
general.dontShowAgain=No ho tornis a mostrar
|
general.dontShowAgain=No ho tornis a mostrar
|
||||||
general.dontAskAgain=Don’t Ask Again
|
general.dontAskAgain=No m'ho tornis a demanar
|
||||||
general.remindMeLater=Remind Me Later
|
general.remindMeLater=Recorda-m'ho més tard
|
||||||
general.fix=Arregla…
|
general.fix=Arregla…
|
||||||
general.tryAgain=Torna-ho a provar
|
general.tryAgain=Torna-ho a provar
|
||||||
general.tryLater=Prova-ho després
|
general.tryLater=Prova-ho després
|
||||||
general.showDirectory=Mostra el directori
|
general.showDirectory=Mostra el directori
|
||||||
general.showInLibrary=Show in Library
|
general.showInLibrary=Mostra a la biblioteca
|
||||||
general.continue=Continua
|
general.continue=Continua
|
||||||
general.copy=Copia
|
general.copy=Copia
|
||||||
general.copyToClipboard=Copia al portaretalls
|
general.copyToClipboard=Copia al portaretalls
|
||||||
|
|
@ -86,18 +86,19 @@ general.nMegabytes=%S MB
|
||||||
general.item=Element
|
general.item=Element
|
||||||
general.pdf=PDF
|
general.pdf=PDF
|
||||||
general.back=Enrere
|
general.back=Enrere
|
||||||
general.languages=Languages
|
general.languages=Llengües
|
||||||
general.default=Default
|
general.default=Per defecte
|
||||||
general.custom=Custom
|
general.custom=Personalitzat
|
||||||
general.loading=Loading…
|
general.loading=S'està carregant…
|
||||||
general.richText=Rich Text
|
general.richText=Text enriquit
|
||||||
general.clearSelection=Clear Selection
|
general.clearSelection=Buida la selecció
|
||||||
|
general.insert=Insereix
|
||||||
|
|
||||||
general.yellow=Yellow
|
general.yellow=Groc
|
||||||
general.red=Red
|
general.red=Vermell
|
||||||
general.green=Green
|
general.green=Verd
|
||||||
general.blue=Blue
|
general.blue=Blau
|
||||||
general.purple=Purple
|
general.purple=Lila
|
||||||
|
|
||||||
general.operationInProgress=Una operació del Zotero està actualment en curs.
|
general.operationInProgress=Una operació del Zotero està actualment en curs.
|
||||||
general.operationInProgress.waitUntilFinished=Espereu fins que hagi acabat.
|
general.operationInProgress.waitUntilFinished=Espereu fins que hagi acabat.
|
||||||
|
|
@ -105,15 +106,16 @@ general.operationInProgress.waitUntilFinishedAndTryAgain=Si us plau, espereu fin
|
||||||
|
|
||||||
networkError.connectionNotSecure=El %S no ha pogut establir una connexió segura.
|
networkError.connectionNotSecure=El %S no ha pogut establir una connexió segura.
|
||||||
networkError.errorViaProxy=S'ha produït un error en connectar-se a través del servidor intermediari
|
networkError.errorViaProxy=S'ha produït un error en connectar-se a través del servidor intermediari
|
||||||
networkError.connectionMonitored=Your connection is likely being monitored, and %S has not been configured to trust the intermediate server.
|
networkError.connectionMonitored=La vostra connexió possiblement està monitorada, i el %S no està configurat per a confiar en el servidor intermediari.
|
||||||
|
|
||||||
about.createdBy=El %1$S és un projecte de %2$S i està desenvolupat per una [comunitat global].
|
about.createdBy=El %1$S és un projecte de %2$S i està desenvolupat per una [comunitat global].
|
||||||
about.openSource=El %S és [programari de codi obert] i depèn de molts altres [projectes de codi obert excepcionals].
|
about.openSource=El %S és [programari de codi obert] i depèn de molts altres [projectes de codi obert excepcionals].
|
||||||
about.getInvolved=Voleu ajudar-hi? [Impliqueu-vos-hi] avui mateix!
|
about.getInvolved=Voleu ajudar-hi? [Impliqueu-vos-hi] avui mateix!
|
||||||
|
|
||||||
punctuation.openingQMark=“
|
punctuation.openingQMark=«
|
||||||
punctuation.closingQMark=”
|
punctuation.closingQMark=»
|
||||||
punctuation.colon=:
|
punctuation.colon=:
|
||||||
|
punctuation.colon.withString=%S:
|
||||||
punctuation.ellipsis=…
|
punctuation.ellipsis=…
|
||||||
|
|
||||||
install.quickStartGuide=Guia d'inici ràpid
|
install.quickStartGuide=Guia d'inici ràpid
|
||||||
|
|
@ -175,7 +177,7 @@ dataDir.selectDir=Selecciona el directori de dades per al Zotero
|
||||||
dataDir.selectNewDir=Seleccioneu un nou directori de dades del %S
|
dataDir.selectNewDir=Seleccioneu un nou directori de dades del %S
|
||||||
dataDir.changeDataDirectory=Canvia el directori de dades…
|
dataDir.changeDataDirectory=Canvia el directori de dades…
|
||||||
dataDir.chooseNewDataDirectory=Trieu un directori de dades nou…
|
dataDir.chooseNewDataDirectory=Trieu un directori de dades nou…
|
||||||
dataDir.cannotBeSetWithAlternative=The data directory cannot be set to a “%S” directory. Did you mean %S?
|
dataDir.cannotBeSetWithAlternative=El directori de dades no es pot definir en un directori del «%S». Volíeu dir %S?
|
||||||
dataDir.cannotBeLinkedAttachmentBaseDirectory=El directori de dades no pot definir-se en la mateixa ubicació que el directori base d'adjuncions enllaçades.
|
dataDir.cannotBeLinkedAttachmentBaseDirectory=El directori de dades no pot definir-se en la mateixa ubicació que el directori base d'adjuncions enllaçades.
|
||||||
dataDir.unsafeLocation.selected.cloud=Emmagatzemar el directori de dades en una carpeta d'emmagatzematge al núvol molt probablement corromprà la vostra base de dades.
|
dataDir.unsafeLocation.selected.cloud=Emmagatzemar el directori de dades en una carpeta d'emmagatzematge al núvol molt probablement corromprà la vostra base de dades.
|
||||||
dataDir.unsafeLocation.selected.areYouSure=Esteu segur que voleu utilitzar aquesta ubicació?
|
dataDir.unsafeLocation.selected.areYouSure=Esteu segur que voleu utilitzar aquesta ubicació?
|
||||||
|
|
@ -236,7 +238,7 @@ date.relative.daysAgo.multiple=Fa %S dies
|
||||||
date.relative.yearsAgo.one=Fa 1 any
|
date.relative.yearsAgo.one=Fa 1 any
|
||||||
date.relative.yearsAgo.multiple=Fa %S anys
|
date.relative.yearsAgo.multiple=Fa %S anys
|
||||||
|
|
||||||
pane.collections.title=Collections
|
pane.collections.title=Col·leccions
|
||||||
pane.collections.delete.title=Suprimeix la col·lecció
|
pane.collections.delete.title=Suprimeix la col·lecció
|
||||||
pane.collections.delete=Segur que voleu eliminar la col·lecció seleccionada?
|
pane.collections.delete=Segur que voleu eliminar la col·lecció seleccionada?
|
||||||
pane.collections.delete.keepItems=Els elements d'aquesta col·lecció no s'esborraran
|
pane.collections.delete.keepItems=Els elements d'aquesta col·lecció no s'esborraran
|
||||||
|
|
@ -308,7 +310,7 @@ pane.items.intro.text1=Us donem la benvinguda a %S!
|
||||||
pane.items.intro.text2=Consulteu la [guia de primers passos] per a aprendre a confeccionar la vostra biblioteca, i assegureu-vos d'[instal·lar un %S] per a poder afegir elements al %S a mesura que navegueu.
|
pane.items.intro.text2=Consulteu la [guia de primers passos] per a aprendre a confeccionar la vostra biblioteca, i assegureu-vos d'[instal·lar un %S] per a poder afegir elements al %S a mesura que navegueu.
|
||||||
pane.items.intro.text3=Utilitzeu el %S en un altre ordinador? [Configureu la sincronització] per a reprendre-ho allà on ho hàgiu deixat.
|
pane.items.intro.text3=Utilitzeu el %S en un altre ordinador? [Configureu la sincronització] per a reprendre-ho allà on ho hàgiu deixat.
|
||||||
|
|
||||||
pane.items.title=Items
|
pane.items.title=Elements
|
||||||
pane.items.loading=S'estan carregant els elements…
|
pane.items.loading=S'estan carregant els elements…
|
||||||
pane.items.loadError=S'ha produït un error en carregar la llista d'elements
|
pane.items.loadError=S'ha produït un error en carregar la llista d'elements
|
||||||
pane.items.columnChooser.moreColumns=Més columnes
|
pane.items.columnChooser.moreColumns=Més columnes
|
||||||
|
|
@ -327,22 +329,27 @@ pane.items.remove.multiple=Segur que voleu eliminar els elements seleccionats d'
|
||||||
pane.items.removeFromPublications.title=Suprimeix de les meves publicacions
|
pane.items.removeFromPublications.title=Suprimeix de les meves publicacions
|
||||||
pane.items.removeFromPublications=Esteu segur que voleu suprimir l'element seleccionat de 'Les meves publicacions'?
|
pane.items.removeFromPublications=Esteu segur que voleu suprimir l'element seleccionat de 'Les meves publicacions'?
|
||||||
pane.items.removeFromPublications.multiple=Esteu segur que voleu suprimir els elements seleccionats de 'Les meves publicacions'?
|
pane.items.removeFromPublications.multiple=Esteu segur que voleu suprimir els elements seleccionats de 'Les meves publicacions'?
|
||||||
pane.items.menu.addNoteFromAnnotations=Add Note from Annotations
|
pane.items.removeRecursive.title=Suprimeix de la col·lecció i de les subcol·leccions
|
||||||
pane.items.menu.addNoteFromAnnotations.multiple=Add Notes from Annotations
|
pane.items.removeRecursive=Esteu segur que voleu eliminar l'element seleccionat d'aquesta col·lecció i de totes les subcol·leccions?
|
||||||
|
pane.items.removeRecursive.multiple=Esteu segur que voleu eliminar els elements seleccionats d'aquesta col·lecció i de totes les subcol·leccions?
|
||||||
|
pane.items.menu.addNoteFromAnnotations=Afegeix nota de les anotacions
|
||||||
|
pane.items.menu.createNoteFromAnnotations=Crea una nota de les anotacions
|
||||||
pane.items.menu.findAvailablePDF=Cerca els PDF disponibles
|
pane.items.menu.findAvailablePDF=Cerca els PDF disponibles
|
||||||
pane.items.menu.findAvailablePDF.multiple=Cerca els PDF disponibles
|
pane.items.menu.findAvailablePDF.multiple=Cerca els PDF disponibles
|
||||||
pane.items.menu.addToCollection=Add to Collection
|
pane.items.menu.addToCollection=Afegeix a la col·lecció
|
||||||
pane.items.menu.remove=Elimina l'element de la col·lecció...
|
pane.items.menu.remove=Elimina l'element de la col·lecció...
|
||||||
pane.items.menu.remove.multiple=Elimina els elements de la col·lecció...
|
pane.items.menu.remove.multiple=Elimina els elements de la col·lecció...
|
||||||
pane.items.menu.removeFromPublications=Suprimeix l'element de les meves publicacions…
|
pane.items.menu.removeFromPublications=Suprimeix l'element de les meves publicacions…
|
||||||
pane.items.menu.removeFromPublications.multiple=Suprimeix els elements de les meves publicacions…
|
pane.items.menu.removeFromPublications.multiple=Suprimeix els elements de les meves publicacions…
|
||||||
pane.items.menu.moveToTrash=Desplaça l'element a la paperera.
|
pane.items.menu.moveToTrash=Desplaça l'element a la paperera.
|
||||||
pane.items.menu.moveToTrash.multiple=Desplaça els elements a la paperera...
|
pane.items.menu.moveToTrash.multiple=Desplaça els elements a la paperera...
|
||||||
pane.items.menu.delete=Delete Permanently…
|
pane.items.menu.delete=Elimina permanentment…
|
||||||
pane.items.menu.export=Exporta l'element seleccionat...
|
pane.items.menu.export=Exporta l'element seleccionat...
|
||||||
pane.items.menu.export.multiple=Exporta els elements seleccionats...
|
pane.items.menu.export.multiple=Exporta els elements seleccionats...
|
||||||
pane.items.menu.exportNote=Export Note…
|
pane.items.menu.exportNote=Exporta la nota…
|
||||||
pane.items.menu.exportNote.multiple=Export Notes…
|
pane.items.menu.exportNote.multiple=Exporta les notes…
|
||||||
|
pane.items.menu.exportPDF=Exporta el PDF…
|
||||||
|
pane.items.menu.exportPDF.multiple=Exporta els PDF…
|
||||||
pane.items.menu.createBib=Crea una bibliografia a partir de l'element seleccionat...
|
pane.items.menu.createBib=Crea una bibliografia a partir de l'element seleccionat...
|
||||||
pane.items.menu.createBib.multiple=Crea una bibliografia a partir dels elements seleccionats...
|
pane.items.menu.createBib.multiple=Crea una bibliografia a partir dels elements seleccionats...
|
||||||
pane.items.menu.generateReport=Genera un informe a partir de l'element seleccionat...
|
pane.items.menu.generateReport=Genera un informe a partir de l'element seleccionat...
|
||||||
|
|
@ -355,6 +362,8 @@ pane.items.menu.createParent=Crea un element pare…
|
||||||
pane.items.menu.createParent.multiple=Crea elements pare
|
pane.items.menu.createParent.multiple=Crea elements pare
|
||||||
pane.items.menu.renameAttachments=Canvia el nom del fitxer amb les metadades ascendents
|
pane.items.menu.renameAttachments=Canvia el nom del fitxer amb les metadades ascendents
|
||||||
pane.items.menu.renameAttachments.multiple=Canvia els noms del fitxers amb les metadades ascendents
|
pane.items.menu.renameAttachments.multiple=Canvia els noms del fitxers amb les metadades ascendents
|
||||||
|
pane.items.menu.duplicateAndConvert.toBookSection=Crea una secció de llibre
|
||||||
|
pane.items.menu.duplicateAndConvert.toBook=Crea un llibre d'una secció de llibre
|
||||||
pane.items.showItemInLibrary=Mostra l'element a la biblioteca
|
pane.items.showItemInLibrary=Mostra l'element a la biblioteca
|
||||||
|
|
||||||
pane.items.letter.oneParticipant=Carta a %S
|
pane.items.letter.oneParticipant=Carta a %S
|
||||||
|
|
@ -397,7 +406,7 @@ pane.item.notes.allNotes=Totes les notes
|
||||||
pane.item.notes.untitled=Nota sense títol
|
pane.item.notes.untitled=Nota sense títol
|
||||||
pane.item.notes.delete.confirm=Segur que voleu eliminar aquesta nota?
|
pane.item.notes.delete.confirm=Segur que voleu eliminar aquesta nota?
|
||||||
pane.item.notes.count=%1$S nota;%1$S notes
|
pane.item.notes.count=%1$S nota;%1$S notes
|
||||||
pane.item.notes.ignoreMissingImage=Some note images are missing and cannot be copied.
|
pane.item.notes.ignoreMissingImage=Falten imatges de notes i no poden copiar-se.
|
||||||
pane.item.attachments.rename.title=Nou títol:
|
pane.item.attachments.rename.title=Nou títol:
|
||||||
pane.item.attachments.rename.renameAssociatedFile=Canvia el nom del fitxer associat
|
pane.item.attachments.rename.renameAssociatedFile=Canvia el nom del fitxer associat
|
||||||
pane.item.attachments.rename.error=S'ha produït un error quan es canviava el nom del fitxer.
|
pane.item.attachments.rename.error=S'ha produït un error quan es canviava el nom del fitxer.
|
||||||
|
|
@ -408,13 +417,23 @@ pane.item.attachments.fileNotFound.text2.stored=Potser s'ha mogut o eliminat for
|
||||||
pane.item.attachments.fileNotFound.text2.stored.notOnServer=Potser s'ha mogut o eliminat fora del %1$S o, si s'ha afegit el fitxer en un altre ordinador, podria no haver-se sincronitzat amb el %2$S.
|
pane.item.attachments.fileNotFound.text2.stored.notOnServer=Potser s'ha mogut o eliminat fora del %1$S o, si s'ha afegit el fitxer en un altre ordinador, podria no haver-se sincronitzat amb el %2$S.
|
||||||
pane.item.attachments.fileNotFound.text2.linked=Potser s'ha mogut o eliminat fora del %1$S o potser s'ha configurat incorrectament un directori base d'adjuncions enllaçades en un dels vostres ordinadors.
|
pane.item.attachments.fileNotFound.text2.linked=Potser s'ha mogut o eliminat fora del %1$S o potser s'ha configurat incorrectament un directori base d'adjuncions enllaçades en un dels vostres ordinadors.
|
||||||
pane.item.attachments.delete.confirm=Estàs segur que vols eliminar aquest arxiu adjunt?
|
pane.item.attachments.delete.confirm=Estàs segur que vols eliminar aquest arxiu adjunt?
|
||||||
pane.item.attachments.count.zero=Cap fitxer adjunt:
|
pane.item.attachments.autoRelink.title=Fitxer ubicat automàticament
|
||||||
pane.item.attachments.count.singular=%S arxiu adjunt:
|
pane.item.attachments.autoRelink.text1=No s'ha pogut trobar el fitxer a la ubicació especificada, però s'ha trobat un fitxer amb el mateix nom en el directori base d'adjuncions enllaçades:
|
||||||
pane.item.attachments.count.plural=%S fitxers adjunts:
|
pane.item.attachments.autoRelink.text2=Antiga ubicació: %S
|
||||||
pane.item.attachments.has=Has attachment
|
pane.item.attachments.autoRelink.text3=Nova ubicació: %S
|
||||||
pane.item.attachments.hasPDF=Has PDF attachment
|
pane.item.attachments.autoRelink.text4=El %1$S pot tornar a enllaçar aquesta adjunció.
|
||||||
pane.item.attachments.hasSnapshot=Has snapshot
|
pane.item.attachments.autoRelink.relink=Torna a enllaçar
|
||||||
pane.item.attachments.hasLink=Has link
|
pane.item.attachments.autoRelinkOthers.title=S'han trobat fitxers addicionals
|
||||||
|
pane.item.attachments.autoRelinkOthers.text=S'ha trobat una altra adjunció no enllaçada en la biblioteca del mateix directori. Voleu tornar a enllaçar l'adjunció també?; S'han trobat %S altres adjuncions no enllaçades en la biblioteca del mateix directori. Voleu tornar a enllaçar les adjuncions ubicades?
|
||||||
|
pane.item.attachments.autoRelink.locateManually=Ubica manualment…
|
||||||
|
pane.item.attachments.autoRelink.relinkAll=Torna a enllaçar tot
|
||||||
|
pane.item.attachments.count.zero=Cap adjunció:
|
||||||
|
pane.item.attachments.count.singular=%S adjunció:
|
||||||
|
pane.item.attachments.count.plural=%S adjuncions:
|
||||||
|
pane.item.attachments.has=Té una adjunció
|
||||||
|
pane.item.attachments.hasPDF=Té una adjunció PDF
|
||||||
|
pane.item.attachments.hasSnapshot=Té una captura
|
||||||
|
pane.item.attachments.hasLink=Té un enllaç
|
||||||
pane.item.attachments.select=Selecciona un fitxer
|
pane.item.attachments.select=Selecciona un fitxer
|
||||||
pane.item.attachments.PDF.installTools.title=PDF Tools no es troba instal·lat
|
pane.item.attachments.PDF.installTools.title=PDF Tools no es troba instal·lat
|
||||||
pane.item.attachments.PDF.installTools.text=Per a utilitzar aquesta funcionalitat, heu d'instal·lar primer les eines PDF en la subfinestra Cerca de les preferències del Zotero.
|
pane.item.attachments.PDF.installTools.text=Per a utilitzar aquesta funcionalitat, heu d'instal·lar primer les eines PDF en la subfinestra Cerca de les preferències del Zotero.
|
||||||
|
|
@ -430,7 +449,7 @@ pane.item.related.count.zero=Cap element relacionat:
|
||||||
pane.item.related.count.singular=%S element relacionat:
|
pane.item.related.count.singular=%S element relacionat:
|
||||||
pane.item.related.count.plural=%S elements relacionats:
|
pane.item.related.count.plural=%S elements relacionats:
|
||||||
pane.item.parentItem=Element ascendent
|
pane.item.parentItem=Element ascendent
|
||||||
pane.item.viewOnline.tooltip=Go to this item online
|
pane.item.viewOnline.tooltip=Vés a aquest element en línia
|
||||||
|
|
||||||
pane.context.noParent=No hi ha cap element pare
|
pane.context.noParent=No hi ha cap element pare
|
||||||
pane.context.itemNotes=Notes dels elements
|
pane.context.itemNotes=Notes dels elements
|
||||||
|
|
@ -439,7 +458,7 @@ pane.context.noNotes=Cap nota
|
||||||
|
|
||||||
itemTypes.note=Nota
|
itemTypes.note=Nota
|
||||||
itemTypes.annotation=Anotació
|
itemTypes.annotation=Anotació
|
||||||
itemTypes.attachment=Fitxer adjunt
|
itemTypes.attachment=Adjunció
|
||||||
itemTypes.book=Llibre
|
itemTypes.book=Llibre
|
||||||
itemTypes.bookSection=Capítol d'un llibre
|
itemTypes.bookSection=Capítol d'un llibre
|
||||||
itemTypes.journalArticle=Article de revista acadèmica
|
itemTypes.journalArticle=Article de revista acadèmica
|
||||||
|
|
@ -474,7 +493,7 @@ itemTypes.conferencePaper=Text d'una conferència
|
||||||
itemTypes.document=Document
|
itemTypes.document=Document
|
||||||
itemTypes.encyclopediaArticle=Article enciclopèdic
|
itemTypes.encyclopediaArticle=Article enciclopèdic
|
||||||
itemTypes.dictionaryEntry=Entrada de diccionari
|
itemTypes.dictionaryEntry=Entrada de diccionari
|
||||||
itemTypes.preprint=Preprint
|
itemTypes.preprint=Prepublicació
|
||||||
|
|
||||||
itemFields.itemType=Tipus
|
itemFields.itemType=Tipus
|
||||||
itemFields.title=Títol
|
itemFields.title=Títol
|
||||||
|
|
@ -483,7 +502,7 @@ itemFields.dateModified=Modificat
|
||||||
itemFields.source=Font
|
itemFields.source=Font
|
||||||
itemFields.notes=Notes
|
itemFields.notes=Notes
|
||||||
itemFields.tags=Etiquetes
|
itemFields.tags=Etiquetes
|
||||||
itemFields.attachments=Fitxers adjunts
|
itemFields.attachments=Adjuncions
|
||||||
itemFields.related=Elements relacionats
|
itemFields.related=Elements relacionats
|
||||||
itemFields.url=URL
|
itemFields.url=URL
|
||||||
itemFields.rights=Drets
|
itemFields.rights=Drets
|
||||||
|
|
@ -587,10 +606,10 @@ itemFields.issuingAuthority=Autoritat emissora
|
||||||
itemFields.filingDate=Data de presentació
|
itemFields.filingDate=Data de presentació
|
||||||
itemFields.genre=Gènere
|
itemFields.genre=Gènere
|
||||||
itemFields.archive=Arxiu
|
itemFields.archive=Arxiu
|
||||||
itemFields.attachmentPDF=PDF Attachment
|
itemFields.attachmentPDF=Adjunció PDF
|
||||||
itemFields.repository=Repository
|
itemFields.repository=Repositori
|
||||||
itemFields.archiveID=Archive ID
|
itemFields.archiveID=ID d'arxiu
|
||||||
itemFields.citationKey=Citation Key
|
itemFields.citationKey=Clau de cita
|
||||||
|
|
||||||
creatorTypes.author=Autor
|
creatorTypes.author=Autor
|
||||||
creatorTypes.contributor=Col·laborador
|
creatorTypes.contributor=Col·laborador
|
||||||
|
|
@ -662,7 +681,7 @@ attachment.fullText=Text complet
|
||||||
attachment.acceptedVersion=Versió acceptada
|
attachment.acceptedVersion=Versió acceptada
|
||||||
attachment.submittedVersion=Versió enviada
|
attachment.submittedVersion=Versió enviada
|
||||||
attachment.convertToStored.title=Converteix a fitxer emmagatzemat;Converteix a fitxers emmagatzemats
|
attachment.convertToStored.title=Converteix a fitxer emmagatzemat;Converteix a fitxers emmagatzemats
|
||||||
attachment.convertToStored.text=%1$S adjunció es convertirà de fitxer adjunt a fitxer emmagatzemat.;%1$S adjuncions es convertiran de fitxers adjunts a fitxers emmagatzemats.
|
attachment.convertToStored.text=%1$S adjunció es convertirà de fitxer enllaçat a fitxer emmagatzemat.;%1$S adjuncions es convertiran de fitxers enllaçats a fitxers emmagatzemats.
|
||||||
attachment.convertToStored.deleteOriginal=Elimina el fitxer original després d'emmagatzemar-lo;Elimina els fitxers originals després d'emmagatzemar-los
|
attachment.convertToStored.deleteOriginal=Elimina el fitxer original després d'emmagatzemar-lo;Elimina els fitxers originals després d'emmagatzemar-los
|
||||||
|
|
||||||
db.dbCorrupted=Sembla que la base de dades de %1$S «%2$S» s'ha corromput.
|
db.dbCorrupted=Sembla que la base de dades de %1$S «%2$S» s'ha corromput.
|
||||||
|
|
@ -709,7 +728,7 @@ zotero.preferences.sync.reset.restoreToServer.button=Reemplaça les dades en la
|
||||||
zotero.preferences.sync.reset.fileSyncHistory=En la sincronització següent, el %1$S comprovarà tots els fitxers adjunts en el «%2$S» respecte al dispositu d'emmagatzematge. Si hi ha cap fitxer d'adjunt remot que no hi sigui localment, es baixarà; i els fitxers adjunts locals que no hi siguin remotament, es pujaran.\n\nAquesta opció no és necessària durant l'ús normal.
|
zotero.preferences.sync.reset.fileSyncHistory=En la sincronització següent, el %1$S comprovarà tots els fitxers adjunts en el «%2$S» respecte al dispositu d'emmagatzematge. Si hi ha cap fitxer d'adjunt remot que no hi sigui localment, es baixarà; i els fitxers adjunts locals que no hi siguin remotament, es pujaran.\n\nAquesta opció no és necessària durant l'ús normal.
|
||||||
zotero.preferences.sync.reset.fileSyncHistory.cleared=S'ha esborrat l'historial de sincronització de fitxers de «%S».
|
zotero.preferences.sync.reset.fileSyncHistory.cleared=S'ha esborrat l'historial de sincronització de fitxers de «%S».
|
||||||
|
|
||||||
zotero.preferences.search.rebuildIndex=Reconstruir índex
|
zotero.preferences.search.rebuildIndex=Reconstrueix l'índex
|
||||||
zotero.preferences.search.rebuildWarning=Voleu reconstruir l'índex sencer? Això pot tardar una mica.\n\nPer indexar només els elements que no han estat indexats feu servir %S.
|
zotero.preferences.search.rebuildWarning=Voleu reconstruir l'índex sencer? Això pot tardar una mica.\n\nPer indexar només els elements que no han estat indexats feu servir %S.
|
||||||
zotero.preferences.search.clearIndex=Neteja l'índex
|
zotero.preferences.search.clearIndex=Neteja l'índex
|
||||||
zotero.preferences.search.clearWarning=Després de netejar l'índex el contingut dels fitxers adjunts no serà cercable.\n\nEls enllaços web no es poden reindexar sense tornar a visitar la pàgina. Per a deixar els enllaços web indexats escull %S.
|
zotero.preferences.search.clearWarning=Després de netejar l'índex el contingut dels fitxers adjunts no serà cercable.\n\nEls enllaços web no es poden reindexar sense tornar a visitar la pàgina. Per a deixar els enllaços web indexats escull %S.
|
||||||
|
|
@ -719,10 +738,11 @@ zotero.preferences.export.quickCopy.citationStyles=Estils de cita
|
||||||
zotero.preferences.export.quickCopy.exportFormats=Formats d'exportació
|
zotero.preferences.export.quickCopy.exportFormats=Formats d'exportació
|
||||||
zotero.preferences.export.quickCopy.instructions=La còpia ràpida us permet exportar elements ràpidament en un format donat. Podeu copiar elements seleccionats al porta-retalls prement %S o arrossegant elements directament en un quatre de text d'un altre programa.
|
zotero.preferences.export.quickCopy.instructions=La còpia ràpida us permet exportar elements ràpidament en un format donat. Podeu copiar elements seleccionats al porta-retalls prement %S o arrossegant elements directament en un quatre de text d'un altre programa.
|
||||||
zotero.preferences.export.quickCopy.citationInstructions=Per als estils de cita, podeu copiar les cites o les notes al peu prement %S o la tecla Maj abans d'arrossegar els elements.
|
zotero.preferences.export.quickCopy.citationInstructions=Per als estils de cita, podeu copiar les cites o les notes al peu prement %S o la tecla Maj abans d'arrossegar els elements.
|
||||||
|
zotero.preferences.export.quickCopy.note.htmlOptions.label=Rich Text/HTML
|
||||||
|
|
||||||
zotero.preferences.wordProcessors.installationSuccess=La instal·lació s'ha realitzat amb èxit.
|
zotero.preferences.wordProcessors.installationSuccess=La instal·lació s'ha realitzat amb èxit.
|
||||||
zotero.preferences.wordProcessors.installationError=No s'ha pogut completar la instal·lació perquè s'ha produït un error. Assegureu-vos que el %1$S estigui tancant i llavors reinicieu-lo.
|
zotero.preferences.wordProcessors.installationError=No s'ha pogut completar la instal·lació perquè s'ha produït un error. Assegureu-vos que el %1$S estigui tancant i llavors reinicieu-lo.
|
||||||
zotero.preferences.wordProcessors.manualInstallation.button=Manual Installation
|
zotero.preferences.wordProcessors.manualInstallation.button=Instal·lació manual
|
||||||
zotero.preferences.wordProcessors.installed=El complement %S està instal·lat.
|
zotero.preferences.wordProcessors.installed=El complement %S està instal·lat.
|
||||||
zotero.preferences.wordProcessors.notInstalled=El complement %S no està instal·lat.
|
zotero.preferences.wordProcessors.notInstalled=El complement %S no està instal·lat.
|
||||||
zotero.preferences.wordProcessors.install=Instal·la el connector %S
|
zotero.preferences.wordProcessors.install=Instal·la el connector %S
|
||||||
|
|
@ -773,7 +793,7 @@ fileInterface.viewSupportedFormats=Mostra els formats compatibles...
|
||||||
fileInterface.untitledBibliography=Bibliografia sense títol
|
fileInterface.untitledBibliography=Bibliografia sense títol
|
||||||
fileInterface.bibliographyHTMLTitle=Bibliografia
|
fileInterface.bibliographyHTMLTitle=Bibliografia
|
||||||
fileInterface.importError=S'ha produït un error quan s'intentava importar el fitxer seleccionat. Assegureu-vos que el fitxer és correcte i torneu-ho a intentar.
|
fileInterface.importError=S'ha produït un error quan s'intentava importar el fitxer seleccionat. Assegureu-vos que el fitxer és correcte i torneu-ho a intentar.
|
||||||
fileInterface.importError.translator=An error occurred importing the selected file with “%S”. Please ensure that the file is valid and try again.
|
fileInterface.importError.translator=S'ha produït un error en importar el fitxer seleccionat amb el «%S». Assegureu-vos que el fitxer és vàlid i torneu-ho a provar.
|
||||||
fileInterface.importClipboardNoDataError=No s'han pogut llegir dades importables des del porta-retalls.
|
fileInterface.importClipboardNoDataError=No s'han pogut llegir dades importables des del porta-retalls.
|
||||||
fileInterface.noReferencesError=Els elements seleccionats no contenen cap referència. Seleccioneu una o més referències i tornar-ho a intentar.
|
fileInterface.noReferencesError=Els elements seleccionats no contenen cap referència. Seleccioneu una o més referències i tornar-ho a intentar.
|
||||||
fileInterface.bibliographyGenerationError=S'ha produït un error quan es generava la bibliografia. Torneu-ho a intentar.
|
fileInterface.bibliographyGenerationError=S'ha produït un error quan es generava la bibliografia. Torneu-ho a intentar.
|
||||||
|
|
@ -831,9 +851,9 @@ searchConditions.mapType=Tipus de mapa
|
||||||
searchConditions.medium=Mitjà
|
searchConditions.medium=Mitjà
|
||||||
searchConditions.artworkMedium=Mitjà artístic
|
searchConditions.artworkMedium=Mitjà artístic
|
||||||
searchConditions.dateModified=Data de modificació
|
searchConditions.dateModified=Data de modificació
|
||||||
searchConditions.fulltextContent=Contingut de l'arxiu adjunt
|
searchConditions.fulltextContent=Contingut de l'adjunció
|
||||||
searchConditions.programmingLanguage=Llengua de programació
|
searchConditions.programmingLanguage=Llengua de programació
|
||||||
searchConditions.fileTypeID=Tipus de fitxer adjunt
|
searchConditions.fileTypeID=Tipus de fitxer de l'adjunció
|
||||||
searchConditions.annotationText=Text d'anotació
|
searchConditions.annotationText=Text d'anotació
|
||||||
searchConditions.annotationComment=Comentari d'anotació
|
searchConditions.annotationComment=Comentari d'anotació
|
||||||
|
|
||||||
|
|
@ -845,7 +865,7 @@ fulltext.indexState.queued=En cua
|
||||||
exportOptions.exportNotes=Exporta les notes
|
exportOptions.exportNotes=Exporta les notes
|
||||||
exportOptions.exportFileData=Exporta els fitxers adjunts
|
exportOptions.exportFileData=Exporta els fitxers adjunts
|
||||||
exportOptions.includeAnnotations=Inclou anotacions
|
exportOptions.includeAnnotations=Inclou anotacions
|
||||||
exportOptions.includeAppLinks=Include %S Links
|
exportOptions.includeAppLinks=Inclou enllaços %S
|
||||||
exportOptions.useJournalAbbreviation=Utilitza l'abreviació de la publicació
|
exportOptions.useJournalAbbreviation=Utilitza l'abreviació de la publicació
|
||||||
charset.UTF8withoutBOM=Unicode (UTF-8 sense BOM)
|
charset.UTF8withoutBOM=Unicode (UTF-8 sense BOM)
|
||||||
charset.autoDetect=(Detecció automàtica)
|
charset.autoDetect=(Detecció automàtica)
|
||||||
|
|
@ -864,22 +884,7 @@ citation.showEditor=Mostra editor...
|
||||||
citation.hideEditor=Oculta l'editor...
|
citation.hideEditor=Oculta l'editor...
|
||||||
citation.citations=Cites
|
citation.citations=Cites
|
||||||
citation.notes=Notes
|
citation.notes=Notes
|
||||||
citation.locator.page=Pàgina
|
citation.locator.timestamp=Marca horària
|
||||||
citation.locator.book=Llibre
|
|
||||||
citation.locator.chapter=Capítol
|
|
||||||
citation.locator.column=Columna
|
|
||||||
citation.locator.figure=Figura
|
|
||||||
citation.locator.folio=Infoli
|
|
||||||
citation.locator.issue=Número
|
|
||||||
citation.locator.line=Línia
|
|
||||||
citation.locator.note=Nota
|
|
||||||
citation.locator.opus=Opus
|
|
||||||
citation.locator.paragraph=Paràgraf
|
|
||||||
citation.locator.part=Part
|
|
||||||
citation.locator.section=Secció
|
|
||||||
citation.locator.subverbo=Sub verbo
|
|
||||||
citation.locator.volume=Volum
|
|
||||||
citation.locator.verse=Vers
|
|
||||||
|
|
||||||
report.title.default=Informe del Zotero
|
report.title.default=Informe del Zotero
|
||||||
report.parentItem=Element pare:
|
report.parentItem=Element pare:
|
||||||
|
|
@ -942,10 +947,10 @@ integration.error.misconfiguredWordStartupFolder.fix=El connector no pot aparèi
|
||||||
integration.error.macWordSBPermissionsMissing.title=Hi manca el permís
|
integration.error.macWordSBPermissionsMissing.title=Hi manca el permís
|
||||||
integration.error.macWordSBPermissionsMissing=El Zotero no té permisos per a controlar el Word. Per a atorgar-li:\n\n1) Obriu les preferències del sistema\n2) Feu clic a «Seguretat i privadesa»\n3) Seleccioneu la pestanya de «Privadesa»\n4) Trobeu i seleccioneu «Automatització» a l'esquerra\n5) Marqueu la casella de «Microsoft Word» sota «Zotero»\n6) Reinicieu el Word
|
integration.error.macWordSBPermissionsMissing=El Zotero no té permisos per a controlar el Word. Per a atorgar-li:\n\n1) Obriu les preferències del sistema\n2) Feu clic a «Seguretat i privadesa»\n3) Seleccioneu la pestanya de «Privadesa»\n4) Trobeu i seleccioneu «Automatització» a l'esquerra\n5) Marqueu la casella de «Microsoft Word» sota «Zotero»\n6) Reinicieu el Word
|
||||||
integration.error.macWordSBPermissionsMissing.pre2016=Si «Microsoft Word» no apareix sota «Automatització», assegureu-vos que esteu executant el Word 2011 versió 14.7.7 o superior.
|
integration.error.macWordSBPermissionsMissing.pre2016=Si «Microsoft Word» no apareix sota «Automatització», assegureu-vos que esteu executant el Word 2011 versió 14.7.7 o superior.
|
||||||
integration.error.m1UpgradeOS.title=macOS Upgrade Required
|
integration.error.m1UpgradeOS.title=Cal una actualització del macOS
|
||||||
integration.error.m1UpgradeOS=Citing in Word on an Apple Silicon Mac with macOS 11.3 or earlier is not supported and may cause %S to freeze. Please upgrade to macOS 11.4 or later.
|
integration.error.m1UpgradeOS=No hi ha suport per a citar en el Word amb l'Apple Silicon Mac fent servir un macOS 11.3 o anterior, i pot provocar que el %S es pengi. Actualitzeu-vos al macOS 11.4 o posterior.
|
||||||
integration.error.viewTroubleshootingInfo=Voleu veure les instruccions de resolució de problemes?
|
integration.error.viewTroubleshootingInfo=Voleu veure les instruccions de resolució de problemes?
|
||||||
integration.error.tabUnavailable=The operation cannot be completed because the %S tab is no longer available.
|
integration.error.tabUnavailable=No es pot completar l'operació perquè la pestanya %S ja no és disponible.
|
||||||
|
|
||||||
integration.replace=Substitueix aquest camp del Zotero?
|
integration.replace=Substitueix aquest camp del Zotero?
|
||||||
integration.missingItem.single=Aquest element ja no existeix a la base de dades del Zotero. Voleu seleccionar un altre element?
|
integration.missingItem.single=Aquest element ja no existeix a la base de dades del Zotero. Voleu seleccionar un altre element?
|
||||||
|
|
@ -985,7 +990,7 @@ styles.installStyle=Instal·la estil "%1$S" des de %2$S?
|
||||||
styles.updateStyle=Actualitza l'estil existent "%1$S" amb "%2$S" des de %3$S?
|
styles.updateStyle=Actualitza l'estil existent "%1$S" amb "%2$S" des de %3$S?
|
||||||
styles.installed=L'estil "%S" s'ha instal·lat correctament
|
styles.installed=L'estil "%S" s'ha instal·lat correctament
|
||||||
styles.installError=%S no sembla un fitxer d'estil vàlid.
|
styles.installError=%S no sembla un fitxer d'estil vàlid.
|
||||||
styles.validationWarning="%S" is not a valid CSL 1.0.2 style file, and may not work properly with %S.\n\nAre you sure you want to continue?
|
styles.validationWarning=«%S» no és un fitxer d'estil CSL 1.0.2 vàlid i podria no funcionar correctament amb el %S.\n\nEsteu segur que voleu continuar?
|
||||||
styles.installSourceError=%1$S fa referència a un fitxer inexistent o no vàlid a %2$S com la seva font.
|
styles.installSourceError=%1$S fa referència a un fitxer inexistent o no vàlid a %2$S com la seva font.
|
||||||
styles.deleteStyle=Segur que voleu suprimir l'estil "%1$S"?
|
styles.deleteStyle=Segur que voleu suprimir l'estil "%1$S"?
|
||||||
styles.deleteStyles=Segur que voleu suprimir els estils seleccionats?
|
styles.deleteStyles=Segur que voleu suprimir els estils seleccionats?
|
||||||
|
|
@ -1004,9 +1009,9 @@ sync.resetGroupFilesAndSync=Reinicia els fitxers de grup i sincronitza
|
||||||
sync.skipGroup=Omet el grup
|
sync.skipGroup=Omet el grup
|
||||||
sync.removeGroupsAndSync=Elimina el grup i sincronitza
|
sync.removeGroupsAndSync=Elimina el grup i sincronitza
|
||||||
|
|
||||||
sync.reminder.setUp.message=Back up your library with %S syncing.
|
sync.reminder.setUp.message=Feu una còpia de seguretat de la biblioteca amb la sincronització del %S.
|
||||||
sync.reminder.setUp.action=Set Up Syncing
|
sync.reminder.setUp.action=Configura la sincronització
|
||||||
sync.reminder.autoSync.message=%S hasn’t synced in a while. Do you want to enable automatic syncing?
|
sync.reminder.autoSync.message=El %S fa temps que no se sincronitza. Voleu activar-ne la sincronització automàtica?
|
||||||
|
|
||||||
sync.error.usernameNotSet=No s'ha establit un nom d'usuari
|
sync.error.usernameNotSet=No s'ha establit un nom d'usuari
|
||||||
sync.error.usernameNotSet.text=Cal que introduïu el vostre nom d'usuari i contrasenya de zotero.org en les preferències de Zotero per a sincronitzar amb el servidor de Zotero.
|
sync.error.usernameNotSet.text=Cal que introduïu el vostre nom d'usuari i contrasenya de zotero.org en les preferències de Zotero per a sincronitzar amb el servidor de Zotero.
|
||||||
|
|
@ -1042,8 +1047,8 @@ sync.error.invalidDataError.otherData=Altres dades continuaran sincronitzant-se.
|
||||||
account.unlinkWarning=Si es desvincula el vostre compte, s'evitarà que %S sincronitzi les vostres dades.
|
account.unlinkWarning=Si es desvincula el vostre compte, s'evitarà que %S sincronitzi les vostres dades.
|
||||||
account.unlinkWarning.removeData=Suprimeix les meves dades de %S d'aquest ordinador
|
account.unlinkWarning.removeData=Suprimeix les meves dades de %S d'aquest ordinador
|
||||||
account.unlinkWarning.button=Desvincula el compte
|
account.unlinkWarning.button=Desvincula el compte
|
||||||
account.warning.emptyLibrary=You are about to sync to an empty %1$S database. This could happen if you accidentally deleted the %2$S file in your %1$S data directory or the location of your data directory changed.
|
account.warning.emptyLibrary=Esteu a punt de sincronitzar una base de dades buida de %1$S. Això pot passar perquè heu suprimit accidentalment el fitxer %2$S del vostre directori de dades de %1$S o la ubicació del vostre directori de dades ha canviat.
|
||||||
account.warning.emptyLibrary.dataWillBeDownloaded=If you continue, data in the ‘%1$S’ account will be downloaded to this computer. Your online library won’t be affected.
|
account.warning.emptyLibrary.dataWillBeDownloaded=Si continueu, les dades del compte «%1$S» es baixaran en aquest ordinador. La biblioteca en línia no es veurà afectada.
|
||||||
account.warning.existingDataElsewhere=Si les dades del %S existeixen en un altre lloc de l'ordinador, caldria que les mogueu al directori de dades actual o bé canvieu la ubicació del directori de dades perquè apunti on es troben les dades que ja existeixen.
|
account.warning.existingDataElsewhere=Si les dades del %S existeixen en un altre lloc de l'ordinador, caldria que les mogueu al directori de dades actual o bé canvieu la ubicació del directori de dades perquè apunti on es troben les dades que ja existeixen.
|
||||||
account.lastSyncWithDifferentAccount=La base de dades del %1$S s'ha sincronitzat per darrera vegada amb un compte diferent («%2$S») del que esteu provant de sincronitzar-vos ara («%3$S»). Si continueu, totes les biblioteques de %1$S associades amb el compte «%2$S» se suprimiran d'aquest ordinador.
|
account.lastSyncWithDifferentAccount=La base de dades del %1$S s'ha sincronitzat per darrera vegada amb un compte diferent («%2$S») del que esteu provant de sincronitzar-vos ara («%3$S»). Si continueu, totes les biblioteques de %1$S associades amb el compte «%2$S» se suprimiran d'aquest ordinador.
|
||||||
account.lastSyncWithDifferentAccount.beforeContinuing=Abans de continuar, assegureu-vos que totes les dades i fitxers que voleu conservar estiguin sincronitzats amb el compte «%S» o que tingueu una còpia de seguretat del directori de dades de %S.
|
account.lastSyncWithDifferentAccount.beforeContinuing=Abans de continuar, assegureu-vos que totes les dades i fitxers que voleu conservar estiguin sincronitzats amb el compte «%S» o que tingueu una còpia de seguretat del directori de dades de %S.
|
||||||
|
|
@ -1207,19 +1212,21 @@ lookup.failure.description=El Zotero no ha pogut trobar un registre per a l'iden
|
||||||
lookup.failureToID.description=El Zotero no ha pogut trobar cap dels identificadors de l'entrada. Verifiqueu l'entrada i torneu-ho a intentar.
|
lookup.failureToID.description=El Zotero no ha pogut trobar cap dels identificadors de l'entrada. Verifiqueu l'entrada i torneu-ho a intentar.
|
||||||
lookup.failureTooMany.description=Massa identificadors. Introduïu-ne un només i torneu-ho a provar.
|
lookup.failureTooMany.description=Massa identificadors. Introduïu-ne un només i torneu-ho a provar.
|
||||||
|
|
||||||
createParent.prompt=Enter a DOI, ISBN, PMID, arXiv ID, or ADS Bibcode to identify this file
|
createParent.prompt=Introduïu un DOI, ISBN, PMID, ID d'arXiv or Bibcode ADS per a identificar aquest fitxer
|
||||||
|
|
||||||
locate.online.label=Veure en línia
|
locate.online.label=Veure en línia
|
||||||
locate.pdf.label=Open PDF
|
locate.pdf.label=Obre el PDF
|
||||||
locate.pdfNewWindow.label=Open PDF in New Window
|
locate.pdfNewWindow.label=Obre el PDF en una finestra nova
|
||||||
locate.snapshot.label=Veure l'instantània
|
locate.snapshot.label=Veure l'instantània
|
||||||
locate.file.label=Veure el fitxer
|
locate.file.label=Veure el fitxer
|
||||||
locate.externalViewer.label=Obre en un visor extern
|
locate.externalViewer.label=Obre en un visor extern
|
||||||
locate.internalViewer.label=Obre en el visor intern
|
locate.internalViewer.label=Obre en el visor intern
|
||||||
locate.showFile.label=Mostra el fitxer
|
locate.showFile.label=Mostra el fitxer
|
||||||
locate.libraryLookup.label=Cerca la biblioteca
|
locate.libraryLookup.label=Cerca la biblioteca
|
||||||
|
locate.libraryLookup.noResolver.title=No hi ha cap resolutor OpenURL
|
||||||
|
locate.libraryLookup.noResolver.text=Heu de triar un resolutor OpenURL del tauler Avançat de les preferències del %S
|
||||||
locate.manageLocateEngines=Manage Lookup Engines...
|
locate.manageLocateEngines=Manage Lookup Engines...
|
||||||
locate.locateEngineDescription=Lookup engines help you find resources in your %S library on the web. Engines enabled in this list appear in the Locate drop-down in the toolbar.
|
locate.locateEngineDescription=Els motors de consulta us ajuden a trobar recursos de la vostra biblioteca de %S al web. Els motors s'habiliten en la llista que apareix en el desplegable 'Ubica' de la barra d'eines.
|
||||||
|
|
||||||
standalone.corruptInstallation=La instal·lació del Zotero sembla que està corrupta per una actualització automàtica que ha fallat. Tot i que el Zotero pot continuar funcionant, per a evitar potencials errades, baixeu-ne la darrera versió de https://www.zotero.org/download tan aviat com sigui possible.
|
standalone.corruptInstallation=La instal·lació del Zotero sembla que està corrupta per una actualització automàtica que ha fallat. Tot i que el Zotero pot continuar funcionant, per a evitar potencials errades, baixeu-ne la darrera versió de https://www.zotero.org/download tan aviat com sigui possible.
|
||||||
standalone.addonInstallationFailed.title=La intal·lació del complement ha fallat
|
standalone.addonInstallationFailed.title=La intal·lació del complement ha fallat
|
||||||
|
|
@ -1298,112 +1305,126 @@ noteEditor.copy=Copia
|
||||||
noteEditor.paste=Enganxa
|
noteEditor.paste=Enganxa
|
||||||
noteEditor.rightToLeft=De dreta a esquerra
|
noteEditor.rightToLeft=De dreta a esquerra
|
||||||
noteEditor.leftToRight=D'esquerra a dreta
|
noteEditor.leftToRight=D'esquerra a dreta
|
||||||
noteEditor.updateNotice=This note was edited with a newer version of %1$S.\nPlease update %1$S to make changes.
|
noteEditor.updateNotice=La nota es va editar en una versió més nova del %1$S.\nActualitzeu el %1$S per a fer-ne canvis.
|
||||||
noteEditor.enterLink=Enter Link
|
noteEditor.enterLink=Introdueix un enllaç
|
||||||
noteEditor.heading1=Heading 1
|
noteEditor.heading1=Encapçalament 1
|
||||||
noteEditor.heading2=Heading 2
|
noteEditor.heading2=Encapçalament 2
|
||||||
noteEditor.heading3=Heading 3
|
noteEditor.heading3=Encapçalament 3
|
||||||
noteEditor.paragraph=Paragraph
|
noteEditor.paragraph=Paràgraf
|
||||||
noteEditor.monospaced=Monospaced
|
noteEditor.monospaced=Monoespaiat
|
||||||
noteEditor.bulletList=Bulleted List
|
noteEditor.bulletList=Llista de pics
|
||||||
noteEditor.orderedList=Numbered List
|
noteEditor.orderedList=Llista numerada
|
||||||
noteEditor.blockquote=Block Quote
|
noteEditor.blockquote=Cita en bloc
|
||||||
noteEditor.formatText=Format Text
|
noteEditor.mathBlock=Bloc de matemàtiques
|
||||||
noteEditor.highlightText=Highlight Text
|
noteEditor.formatText=Text formal
|
||||||
noteEditor.removeColor=Remove Color
|
noteEditor.highlightText=Marca el text
|
||||||
noteEditor.bold=Bold
|
noteEditor.removeColor=Elimina el color
|
||||||
noteEditor.italic=Italic
|
noteEditor.bold=Negreta
|
||||||
noteEditor.underline=Underline
|
noteEditor.italic=Cursiva
|
||||||
noteEditor.strikethrough=Strikethrough
|
noteEditor.underline=Subratllat
|
||||||
noteEditor.subscript=Subscript
|
noteEditor.strikethrough=Ratllat
|
||||||
noteEditor.superscript=Superscript
|
noteEditor.subscript=Subíndex
|
||||||
noteEditor.returnToNotesList=Return to Notes List
|
noteEditor.superscript=Superíndex
|
||||||
noteEditor.insertLink=Insert Link
|
noteEditor.returnToNotesList=Torna a la llista de notes
|
||||||
noteEditor.clearFormatting=Clear Formatting
|
noteEditor.insertLink=Insereix un enllaç
|
||||||
noteEditor.align=Align
|
noteEditor.clearFormatting=Neteja el format
|
||||||
noteEditor.alignLeft=Align Left
|
noteEditor.align=Alinea
|
||||||
noteEditor.alignCenter=Align Center
|
noteEditor.alignLeft=Alinea a l'esquerra
|
||||||
noteEditor.alignRight=Align Right
|
noteEditor.alignCenter=Alinea al centre
|
||||||
noteEditor.insertCitation=Insert Citation
|
noteEditor.alignRight=Alinea a la dreta
|
||||||
|
noteEditor.insertCitation=Insereix una cita
|
||||||
noteEditor.more=Més
|
noteEditor.more=Més
|
||||||
noteEditor.find=Find
|
noteEditor.find=Cerca
|
||||||
noteEditor.replace=Replace
|
noteEditor.replace=Reemplaça
|
||||||
noteEditor.previous=Previous
|
noteEditor.previous=Anterior
|
||||||
noteEditor.next=Next
|
noteEditor.next=Següent
|
||||||
noteEditor.replaceNext=Replace
|
noteEditor.replaceNext=Reemplaça
|
||||||
noteEditor.replaceAll=Replace All
|
noteEditor.replaceAll=Reemplaça-ho tot
|
||||||
noteEditor.goToPage=Go to Page
|
noteEditor.goToPage=Vés a la pàgina
|
||||||
noteEditor.showItem=Show Item
|
noteEditor.showItem=Mostra l'element
|
||||||
noteEditor.editCitation=Edit Citation
|
noteEditor.editCitation=Edita la cita
|
||||||
noteEditor.showOnPage=Show on Page
|
noteEditor.showOnPage=Mostra-ho a la pàgina
|
||||||
noteEditor.unlink=Unlink
|
noteEditor.unlink=Desenllaça
|
||||||
noteEditor.set=Set
|
noteEditor.set=Defineix
|
||||||
noteEditor.edit=Edit
|
noteEditor.edit=Edita
|
||||||
noteEditor.addCitation=Add Citation
|
noteEditor.addCitation=Afegeix una cita
|
||||||
noteEditor.removeCitation=Hide Citation
|
noteEditor.removeCitation=Amaga la cita
|
||||||
noteEditor.findAndReplace=Find and Replace
|
noteEditor.findAndReplace=Cerca i reemplaça
|
||||||
noteEditor.editInWindow=Edit in a Separate Window
|
noteEditor.editInWindow=Edita en una finestra separada
|
||||||
noteEditor.applyAnnotationColors=Show Annotation Colors
|
noteEditor.applyAnnotationColors=Mostra els colors d'anotació
|
||||||
noteEditor.removeAnnotationColors=Hide Annotation Colors
|
noteEditor.removeAnnotationColors=Amaga els colors d'anotació
|
||||||
noteEditor.addCitations=Show Annotation Citations
|
noteEditor.addCitations=Mostra les cites d'anotació
|
||||||
noteEditor.removeCitations=Hide Annotation Citations
|
noteEditor.removeCitations=Amaga les cites d'anotació
|
||||||
noteEditor.insertTable=Insert Table
|
noteEditor.image=Imatge
|
||||||
noteEditor.insertRowBefore=Insert Row Above
|
noteEditor.math=Matemàtiques
|
||||||
noteEditor.insertRowAfter=Insert Row Below
|
noteEditor.table=Taula
|
||||||
noteEditor.insertColumnBefore=Insert Column Left
|
noteEditor.copyImage=Copia la imatge
|
||||||
noteEditor.insertColumnAfter=Insert Column Right
|
noteEditor.saveImageAs=Anomena i desa la imatge…
|
||||||
noteEditor.deleteRow=Delete Row
|
noteEditor.insertRowBefore=Insereix una fila a sobre
|
||||||
noteEditor.deleteColumn=Delete Column
|
noteEditor.insertRowAfter=Insereix una fila a sota
|
||||||
noteEditor.deleteTable=Delete Table
|
noteEditor.insertColumnBefore=Insereix una columna a l'esquerra
|
||||||
|
noteEditor.insertColumnAfter=Insereix una columna a la dreta
|
||||||
|
noteEditor.deleteRow=Suprimeix la fila
|
||||||
|
noteEditor.deleteColumn=Suprimeix la columna
|
||||||
|
noteEditor.deleteTable=Suprimeix la taula
|
||||||
|
|
||||||
pdfReader.annotations=Annotations
|
pdfReader.annotations=Anotacions
|
||||||
pdfReader.showAnnotations=Show Annotations
|
pdfReader.showAnnotations=Mostra les anotacions
|
||||||
pdfReader.searchAnnotations=Search Annotations
|
pdfReader.searchAnnotations=Cerca anotacions
|
||||||
pdfReader.noAnnotations=Create an annotation to see it in the sidebar
|
pdfReader.noAnnotations=Creeu una anotació per a veure-la en la barra lateral
|
||||||
pdfReader.addText=Add extracted text
|
pdfReader.noExtractedText=Text no extret
|
||||||
pdfReader.addComment=Add comment
|
pdfReader.addComment=Afegeix un comentari
|
||||||
pdfReader.addTags=Add tags…
|
pdfReader.addTags=Afegeix etiquetes…
|
||||||
pdfReader.highlightText=Highlight Text
|
pdfReader.highlightText=Marca el text
|
||||||
pdfReader.addNote=Add Note
|
pdfReader.addNote=Afegeix una nota
|
||||||
pdfReader.selectArea=Select Area
|
pdfReader.selectArea=Selecciona l'àrea
|
||||||
pdfReader.pickColor=Pick a Color
|
pdfReader.pickColor=Tria un color
|
||||||
pdfReader.addToNote=Add to Note
|
pdfReader.addToNote=Afegeix a la nota
|
||||||
pdfReader.zoomIn=Zoom In
|
pdfReader.zoomIn=Amplia
|
||||||
pdfReader.zoomOut=Zoom Out
|
pdfReader.zoomOut=Redueix
|
||||||
pdfReader.zoomAuto=Automatically Resize
|
pdfReader.zoomAuto=Redimensiona automàticament
|
||||||
pdfReader.zoomPageWidth=Zoom to Page Width
|
pdfReader.zoomPageWidth=Ajusta a l'amplada de la pàgina
|
||||||
pdfReader.zoomPageHeight=Zoom to Page Height
|
pdfReader.zoomPageHeight=Ajusta a l'alçada de la pàgina
|
||||||
|
pdfReader.splitVertically=Divideix verticalment
|
||||||
|
pdfReader.splitHorizontally=Divideix horitzontalment
|
||||||
pdfReader.nextPage=Pàgina següent
|
pdfReader.nextPage=Pàgina següent
|
||||||
pdfReader.previousPage=Pàgina anterior
|
pdfReader.previousPage=Pàgina anterior
|
||||||
pdfReader.page=Pàgina
|
pdfReader.page=Pàgina
|
||||||
pdfReader.readOnly=Només de lectura
|
pdfReader.readOnly=Només de lectura
|
||||||
pdfReader.promptTransferFromPDF.title=Import Annotations
|
pdfReader.promptTransferFromPDF.title=Importa anotacions
|
||||||
pdfReader.promptTransferFromPDF.text=Annotations stored in the PDF file will be moved to %1$S.
|
pdfReader.promptTransferFromPDF.text=Les anotacions emmagatzemades en el fitxer PDF es mouran a %1$S.
|
||||||
pdfReader.promptTransferToPDF.title=Store Annotations in File
|
pdfReader.promptTransferToPDF.title=Emmagatzema les anotacions en un fitxer
|
||||||
pdfReader.promptTransferToPDF.text=Annotations will be transferred to the PDF file and will no longer be editable in %S.
|
pdfReader.promptTransferToPDF.text=Les anotacions es transferiran al fixer PDF i ja no podren ser editades més al %S.
|
||||||
pdfReader.promptPasswordProtected=The operation is not supported for password-protected PDF files.
|
pdfReader.promptPasswordProtected=L'operació no funciona en fitxers PDF protegits amb contrasenya.
|
||||||
pdfReader.editPageNumber=Edit Page Number…
|
pdfReader.promptDeletePages.title=Elimina les pàgines
|
||||||
pdfReader.editHighlightedText=Edit Highlighted Text
|
pdfReader.promptDeletePages.text=Esteu segur que voleu suprimir %1$S pàgina del fitxer PDF?;Esteu segur que voleu suprimir %1$S pàgines del fitxer PDF?
|
||||||
pdfReader.pageNumberPopupHeader=Change page number for:
|
pdfReader.rotateLeft=Gira a l'esquerra
|
||||||
pdfReader.thisAnnotation=This annotation
|
pdfReader.rotateRight=Gira a la dreta
|
||||||
pdfReader.selectedAnnotations=Selected annotations
|
pdfReader.rotate180=Gira 180°
|
||||||
pdfReader.thisPage=This page
|
pdfReader.editPageNumber=Edita el número de pàgina…
|
||||||
pdfReader.thisPageAndLaterPages=This page and later pages
|
pdfReader.editHighlightedText=Edita el text ressaltat
|
||||||
pdfReader.allPages=All pages
|
pdfReader.copyImage=Copia la imatge
|
||||||
pdfReader.autoDetect=Auto-Detect
|
pdfReader.saveImageAs=Anomena i desa la imatge…
|
||||||
pdfReader.deleteAnnotation.singular=Are you sure you want to delete the selected annotation?
|
pdfReader.pageNumberPopupHeader=Canvia el número de la pàgina per:
|
||||||
pdfReader.deleteAnnotation.plural=Are you sure you want to delete the selected annotations?
|
pdfReader.thisAnnotation=Aquesta anotació
|
||||||
|
pdfReader.selectedAnnotations=Anotacions seleccionades
|
||||||
|
pdfReader.thisPage=Aquesta pàgina
|
||||||
|
pdfReader.thisPageAndLaterPages=Aquesta pàgina i posteriors
|
||||||
|
pdfReader.allPages=Totes les pàgines
|
||||||
|
pdfReader.autoDetect=Detecció automàtica
|
||||||
|
pdfReader.deleteAnnotation.singular=Esteu segur que voleu eliminar l'anotació seleccionada?
|
||||||
|
pdfReader.deleteAnnotation.plural=Esteu segur que voleu eliminar les anotacions seleccionades?
|
||||||
|
|
||||||
spellCheck.checkSpelling=Check Spelling
|
spellCheck.checkSpelling=Revisa l'ortografia
|
||||||
spellCheck.addRemoveDictionaries=Add/Remove Dictionaries…
|
spellCheck.addRemoveDictionaries=Afegeix/Suprimeix diccionaris…
|
||||||
spellCheck.dictionaryManager.title=Add/Remove Dictionaries
|
spellCheck.dictionaryManager.title=Afegeix/Suprimeix diccionaris
|
||||||
spellCheck.dictionaryManager.updateAvailable=%S (update available)
|
spellCheck.dictionaryManager.updateAvailable=%S (actualització disponible)
|
||||||
spellCheck.dictionaryManager.error.unableToInstall=Unable to install “%S”:
|
spellCheck.dictionaryManager.error.unableToInstall=No s'ha pogut instal·lar «%S»:
|
||||||
|
|
||||||
tabs.move=Move Tab
|
tabs.move=Mou la pestanya
|
||||||
tabs.moveToStart=Move to Start
|
tabs.moveToStart=Mou a l'inici
|
||||||
tabs.moveToEnd=Move to End
|
tabs.moveToEnd=Mou al final
|
||||||
tabs.moveToWindow=Move to New Window
|
tabs.moveToWindow=Mou a una finestra nova
|
||||||
tabs.duplicate=Duplicate Tab
|
tabs.duplicate=Duplica la pestanya
|
||||||
tabs.undoClose=Reopen Closed Tab;Reopen Closed Tabs
|
tabs.undoClose=Torna a obrir la pestanya tancada;Torna a obrir les pestanyes tancades
|
||||||
tabs.closeOther=Close Other Tabs
|
tabs.closeOther=Tanca les altres pestanyes
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,12 @@
|
||||||
"general_done": {
|
"general_done": {
|
||||||
"message": "Hotovo"
|
"message": "Hotovo"
|
||||||
},
|
},
|
||||||
|
"general_yes": {
|
||||||
|
"message": "Ano"
|
||||||
|
},
|
||||||
|
"general_no": {
|
||||||
|
"message": "Ne"
|
||||||
|
},
|
||||||
"general_tryAgain": {
|
"general_tryAgain": {
|
||||||
"message": "Zkusit znovu"
|
"message": "Zkusit znovu"
|
||||||
},
|
},
|
||||||
|
|
@ -14,6 +20,9 @@
|
||||||
"general_cancel": {
|
"general_cancel": {
|
||||||
"message": "Zrušit"
|
"message": "Zrušit"
|
||||||
},
|
},
|
||||||
|
"general_copyToClipboard": {
|
||||||
|
"message": "Kopírovat do schránky"
|
||||||
|
},
|
||||||
"progressWindow_savingTo": {
|
"progressWindow_savingTo": {
|
||||||
"message": "Ukládám do"
|
"message": "Ukládám do"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
<!ENTITY zotero.preferences.groups.whenCopyingInclude "Při kopírování položek mezi knihovnami zahrnout:">
|
<!ENTITY zotero.preferences.groups.whenCopyingInclude "Při kopírování položek mezi knihovnami zahrnout:">
|
||||||
<!ENTITY zotero.preferences.groups.childNotes "dceřiné poznámky">
|
<!ENTITY zotero.preferences.groups.childNotes "dceřiné poznámky">
|
||||||
<!ENTITY zotero.preferences.groups.childFiles "dceřiné snímky a importované soubory">
|
<!ENTITY zotero.preferences.groups.childFiles "dceřiné snímky a importované soubory">
|
||||||
<!ENTITY zotero.preferences.groups.annotations "annotations">
|
<!ENTITY zotero.preferences.groups.annotations "anotace">
|
||||||
<!ENTITY zotero.preferences.groups.childLinks "dceřiné odkazy">
|
<!ENTITY zotero.preferences.groups.childLinks "dceřiné odkazy">
|
||||||
<!ENTITY zotero.preferences.groups.tags "štítky">
|
<!ENTITY zotero.preferences.groups.tags "štítky">
|
||||||
|
|
||||||
|
|
@ -105,8 +105,8 @@
|
||||||
<!ENTITY zotero.preferences.export.citePaperJournalArticleURL.description "Pokud je tato volba neaktivní, Zotero zahrne URL v případě citování článku (z časopisu, magazínu nebo novin) pouze když článek nemá specifikovaný rozsah stran.">
|
<!ENTITY zotero.preferences.export.citePaperJournalArticleURL.description "Pokud je tato volba neaktivní, Zotero zahrne URL v případě citování článku (z časopisu, magazínu nebo novin) pouze když článek nemá specifikovaný rozsah stran.">
|
||||||
|
|
||||||
<!ENTITY zotero.preferences.quickCopy.caption "Rychlé kopírování">
|
<!ENTITY zotero.preferences.quickCopy.caption "Rychlé kopírování">
|
||||||
<!ENTITY zotero.preferences.quickCopy.itemFormat "Item Format:">
|
<!ENTITY zotero.preferences.quickCopy.itemFormat "Formát položky">
|
||||||
<!ENTITY zotero.preferences.quickCopy.noteFormat "Note Format:">
|
<!ENTITY zotero.preferences.quickCopy.noteFormat "Formát poznámky">
|
||||||
<!ENTITY zotero.preferences.quickCopy.copyAsHTML "Kopírovat jako HTML">
|
<!ENTITY zotero.preferences.quickCopy.copyAsHTML "Kopírovat jako HTML">
|
||||||
<!ENTITY zotero.preferences.quickCopy.siteEditor.setings "Nastavení dle stránky:">
|
<!ENTITY zotero.preferences.quickCopy.siteEditor.setings "Nastavení dle stránky:">
|
||||||
<!ENTITY zotero.preferences.quickCopy.siteEditor.domainPath "Doména/Cesta">
|
<!ENTITY zotero.preferences.quickCopy.siteEditor.domainPath "Doména/Cesta">
|
||||||
|
|
@ -144,7 +144,7 @@
|
||||||
<!ENTITY zotero.preferences.proxies.proxyOptions "Možnosti Proxy">
|
<!ENTITY zotero.preferences.proxies.proxyOptions "Možnosti Proxy">
|
||||||
<!ENTITY zotero.preferences.proxies.desc_before_link "Zotero bude transparentně přesměrovávat požadavky skrz uložené proxy servery. Více informací najdete v">
|
<!ENTITY zotero.preferences.proxies.desc_before_link "Zotero bude transparentně přesměrovávat požadavky skrz uložené proxy servery. Více informací najdete v">
|
||||||
<!ENTITY zotero.preferences.proxies.desc_link "dokumentaci k proxy">
|
<!ENTITY zotero.preferences.proxies.desc_link "dokumentaci k proxy">
|
||||||
<!ENTITY zotero.preferences.proxies.desc_after_link ".">
|
<!ENTITY zotero.preferences.proxies.desc_after_link "pro další informace.">
|
||||||
<!ENTITY zotero.preferences.proxies.transparent "Automaticky přesměrovávat požadavky skrz dříve použité proxy servery.">
|
<!ENTITY zotero.preferences.proxies.transparent "Automaticky přesměrovávat požadavky skrz dříve použité proxy servery.">
|
||||||
<!ENTITY zotero.preferences.proxies.autoRecognize "Automaticky rozpoznávat proxované zdroje">
|
<!ENTITY zotero.preferences.proxies.autoRecognize "Automaticky rozpoznávat proxované zdroje">
|
||||||
<!ENTITY zotero.preferences.proxies.showRedirectNotification "Zobrazovat upozornění při přesměrování přes proxy">
|
<!ENTITY zotero.preferences.proxies.showRedirectNotification "Zobrazovat upozornění při přesměrování přes proxy">
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
<!ENTITY copyCitationCmd.label "Kopírovat citaci">
|
<!ENTITY copyCitationCmd.label "Kopírovat citaci">
|
||||||
<!ENTITY copyBibliographyCmd.label "Kopírovat bibliografii">
|
<!ENTITY copyBibliographyCmd.label "Kopírovat bibliografii">
|
||||||
<!ENTITY copyNoteCmd.label "Copy Note">
|
<!ENTITY copyNoteCmd.label "Kopírovat poznámku">
|
||||||
|
|
||||||
<!ENTITY bidiSwitchPageDirectionItem.label "Přepnout směr stránky">
|
<!ENTITY bidiSwitchPageDirectionItem.label "Přepnout směr stránky">
|
||||||
<!ENTITY bidiSwitchPageDirectionItem.accesskey "g">
|
<!ENTITY bidiSwitchPageDirectionItem.accesskey "g">
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<!ENTITY zotero.general.deselectAll "Odznačit vše">
|
<!ENTITY zotero.general.deselectAll "Odznačit vše">
|
||||||
<!ENTITY zotero.general.edit "Editovat">
|
<!ENTITY zotero.general.edit "Editovat">
|
||||||
<!ENTITY zotero.general.delete "Smazat">
|
<!ENTITY zotero.general.delete "Smazat">
|
||||||
<!ENTITY zotero.general.moveToTrash "Move to Trash">
|
<!ENTITY zotero.general.moveToTrash "Přesunout do Koše">
|
||||||
<!ENTITY zotero.general.ok "OK">
|
<!ENTITY zotero.general.ok "OK">
|
||||||
<!ENTITY zotero.general.cancel "Zrušit">
|
<!ENTITY zotero.general.cancel "Zrušit">
|
||||||
<!ENTITY zotero.general.refresh "Obnovit">
|
<!ENTITY zotero.general.refresh "Obnovit">
|
||||||
|
|
@ -128,8 +128,8 @@
|
||||||
<!ENTITY zotero.toolbar.attachment.add "Uložit kopii souboru...">
|
<!ENTITY zotero.toolbar.attachment.add "Uložit kopii souboru...">
|
||||||
<!ENTITY zotero.toolbar.attachment.weblink "Uložit odkaz na aktuální stránku">
|
<!ENTITY zotero.toolbar.attachment.weblink "Uložit odkaz na aktuální stránku">
|
||||||
<!ENTITY zotero.toolbar.attachment.snapshot "Vytvořit snímek aktuální stránky">
|
<!ENTITY zotero.toolbar.attachment.snapshot "Vytvořit snímek aktuální stránky">
|
||||||
<!ENTITY zotero.toolbar.context.item "Item">
|
<!ENTITY zotero.toolbar.context.item "Položka">
|
||||||
<!ENTITY zotero.toolbar.context.notes "Notes">
|
<!ENTITY zotero.toolbar.context.notes "Poznámky">
|
||||||
|
|
||||||
<!ENTITY zotero.tagSelector.noTagsToDisplay "Žádné štítky k zobrazení">
|
<!ENTITY zotero.tagSelector.noTagsToDisplay "Žádné štítky k zobrazení">
|
||||||
<!ENTITY zotero.tagSelector.loadingTags "Nahrávám štítky...">
|
<!ENTITY zotero.tagSelector.loadingTags "Nahrávám štítky...">
|
||||||
|
|
@ -307,12 +307,10 @@
|
||||||
<!ENTITY zotero.context.addStandaloneNoteFromAnnotations "Add Standalone Note from Annotations">
|
<!ENTITY zotero.context.addStandaloneNoteFromAnnotations "Add Standalone Note from Annotations">
|
||||||
<!ENTITY zotero.context.editInWindow "Edit in a Separate Window">
|
<!ENTITY zotero.context.editInWindow "Edit in a Separate Window">
|
||||||
|
|
||||||
<!ENTITY zotero.pdfReader.firstPage "First Page">
|
<!ENTITY zotero.pdfReader.firstPage "První strana">
|
||||||
<!ENTITY zotero.pdfReader.lastPage "Last Page">
|
<!ENTITY zotero.pdfReader.lastPage "Last Page">
|
||||||
<!ENTITY zotero.pdfReader.back "Back">
|
<!ENTITY zotero.pdfReader.back "Back">
|
||||||
<!ENTITY zotero.pdfReader.forward "Forward">
|
<!ENTITY zotero.pdfReader.forward "Forward">
|
||||||
<!ENTITY zotero.pdfReader.rotateClockwise "Rotate Clockwise">
|
|
||||||
<!ENTITY zotero.pdfReader.rotateCounterclockwise "Rotate Counterclockwise">
|
|
||||||
<!ENTITY zotero.pdfReader.handTool "Hand Tool">
|
<!ENTITY zotero.pdfReader.handTool "Hand Tool">
|
||||||
<!ENTITY zotero.pdfReader.verticalScrolling "Vertical Scrolling">
|
<!ENTITY zotero.pdfReader.verticalScrolling "Vertical Scrolling">
|
||||||
<!ENTITY zotero.pdfReader.horizontalScrolling "Horizontal Scrolling">
|
<!ENTITY zotero.pdfReader.horizontalScrolling "Horizontal Scrolling">
|
||||||
|
|
@ -325,4 +323,9 @@
|
||||||
<!ENTITY zotero.pdfReader.zoomAuto "Automatically Resize">
|
<!ENTITY zotero.pdfReader.zoomAuto "Automatically Resize">
|
||||||
<!ENTITY zotero.pdfReader.zoomPageWidth "Zoom to Page Width">
|
<!ENTITY zotero.pdfReader.zoomPageWidth "Zoom to Page Width">
|
||||||
<!ENTITY zotero.pdfReader.zoomPageHeight "Zoom to Page Height">
|
<!ENTITY zotero.pdfReader.zoomPageHeight "Zoom to Page Height">
|
||||||
|
<!ENTITY zotero.pdfReader.splitVertically "Split Vertically">
|
||||||
|
<!ENTITY zotero.pdfReader.splitHorizontally "Split Horizontally">
|
||||||
<!ENTITY zotero.pdfReader.transferFromPDF "Import Annotations…">
|
<!ENTITY zotero.pdfReader.transferFromPDF "Import Annotations…">
|
||||||
|
<!ENTITY zotero.pdfReader.rotatePageLeft "Rotate Page Left">
|
||||||
|
<!ENTITY zotero.pdfReader.rotatePageRight "Rotate Page Right">
|
||||||
|
<!ENTITY zotero.pdfReader.rotatePage180 "Rotate Page 180°">
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ general.moreInformation=Více informací
|
||||||
general.learnMore=Learn More
|
general.learnMore=Learn More
|
||||||
general.seeForMoreInformation=Pro více informací se podívejte na %S
|
general.seeForMoreInformation=Pro více informací se podívejte na %S
|
||||||
general.open=Otevřít %S
|
general.open=Otevřít %S
|
||||||
general.close=Close
|
general.close=Zavřít
|
||||||
general.enable=Povolit
|
general.enable=Povolit
|
||||||
general.disable=Zakázat
|
general.disable=Zakázat
|
||||||
general.reset=Resetovat
|
general.reset=Resetovat
|
||||||
|
|
@ -71,9 +71,9 @@ general.fix=Fix...
|
||||||
general.tryAgain=Zkusit znovu
|
general.tryAgain=Zkusit znovu
|
||||||
general.tryLater=Zkusit později
|
general.tryLater=Zkusit později
|
||||||
general.showDirectory=Zobrazit adresář
|
general.showDirectory=Zobrazit adresář
|
||||||
general.showInLibrary=Show in Library
|
general.showInLibrary=Ukázat v knihovně
|
||||||
general.continue=Pokračovat
|
general.continue=Pokračovat
|
||||||
general.copy=Copy
|
general.copy=Kopírovat
|
||||||
general.copyToClipboard=Kopírovat do schránky
|
general.copyToClipboard=Kopírovat do schránky
|
||||||
general.cancel=Zrušit
|
general.cancel=Zrušit
|
||||||
general.clear=Vyčistit
|
general.clear=Vyčistit
|
||||||
|
|
@ -89,9 +89,10 @@ general.back=Back
|
||||||
general.languages=Languages
|
general.languages=Languages
|
||||||
general.default=Default
|
general.default=Default
|
||||||
general.custom=Custom
|
general.custom=Custom
|
||||||
general.loading=Loading…
|
general.loading=Nahrává se...
|
||||||
general.richText=Rich Text
|
general.richText=Rich Text
|
||||||
general.clearSelection=Clear Selection
|
general.clearSelection=Clear Selection
|
||||||
|
general.insert=Insert
|
||||||
|
|
||||||
general.yellow=Yellow
|
general.yellow=Yellow
|
||||||
general.red=Red
|
general.red=Red
|
||||||
|
|
@ -114,6 +115,7 @@ about.getInvolved=Chcete pomoci? [Zapojte se] ještě dnes!
|
||||||
punctuation.openingQMark=“
|
punctuation.openingQMark=“
|
||||||
punctuation.closingQMark=”
|
punctuation.closingQMark=”
|
||||||
punctuation.colon=:
|
punctuation.colon=:
|
||||||
|
punctuation.colon.withString=%S:
|
||||||
punctuation.ellipsis=...
|
punctuation.ellipsis=...
|
||||||
|
|
||||||
install.quickStartGuide=Rychlý průvodce
|
install.quickStartGuide=Rychlý průvodce
|
||||||
|
|
@ -327,8 +329,11 @@ pane.items.remove.multiple=Opravdu chcete odstranit vybrané položky z této ko
|
||||||
pane.items.removeFromPublications.title=Odstranit z Mých publikací
|
pane.items.removeFromPublications.title=Odstranit z Mých publikací
|
||||||
pane.items.removeFromPublications=Opravdu chcete odstranit vybranou položku z Mých publikací?
|
pane.items.removeFromPublications=Opravdu chcete odstranit vybranou položku z Mých publikací?
|
||||||
pane.items.removeFromPublications.multiple=Opravdu chcete odstranit vybrané položky z Mých publikací?
|
pane.items.removeFromPublications.multiple=Opravdu chcete odstranit vybrané položky z Mých publikací?
|
||||||
pane.items.menu.addNoteFromAnnotations=Add Note from Annotations
|
pane.items.removeRecursive.title=Remove from Collection and Subcollections
|
||||||
pane.items.menu.addNoteFromAnnotations.multiple=Add Notes from Annotations
|
pane.items.removeRecursive=Are you sure you want to remove the selected item from this collection and all subcollections?
|
||||||
|
pane.items.removeRecursive.multiple=Are you sure you want to remove the selected items from this collection and all subcollections?
|
||||||
|
pane.items.menu.addNoteFromAnnotations=Přidat poznámku z anotací
|
||||||
|
pane.items.menu.createNoteFromAnnotations=Create Note from Annotations
|
||||||
pane.items.menu.findAvailablePDF=Najít dostupné PDF
|
pane.items.menu.findAvailablePDF=Najít dostupné PDF
|
||||||
pane.items.menu.findAvailablePDF.multiple=Najít dostupná PDF
|
pane.items.menu.findAvailablePDF.multiple=Najít dostupná PDF
|
||||||
pane.items.menu.addToCollection=Add to Collection
|
pane.items.menu.addToCollection=Add to Collection
|
||||||
|
|
@ -338,11 +343,13 @@ pane.items.menu.removeFromPublications=Odstranit položku z Mých publikací
|
||||||
pane.items.menu.removeFromPublications.multiple=Odstranit položky z Mých publikací...
|
pane.items.menu.removeFromPublications.multiple=Odstranit položky z Mých publikací...
|
||||||
pane.items.menu.moveToTrash=Přesunout položku do Koše...
|
pane.items.menu.moveToTrash=Přesunout položku do Koše...
|
||||||
pane.items.menu.moveToTrash.multiple=Přesunout položky do Koše...
|
pane.items.menu.moveToTrash.multiple=Přesunout položky do Koše...
|
||||||
pane.items.menu.delete=Delete Permanently…
|
pane.items.menu.delete=Definitivně smazat...
|
||||||
pane.items.menu.export=Exportovat vybranou položku...
|
pane.items.menu.export=Exportovat vybranou položku...
|
||||||
pane.items.menu.export.multiple=Exportovat vybrané položky...
|
pane.items.menu.export.multiple=Exportovat vybrané položky...
|
||||||
pane.items.menu.exportNote=Export Note…
|
pane.items.menu.exportNote=Export Note…
|
||||||
pane.items.menu.exportNote.multiple=Export Notes…
|
pane.items.menu.exportNote.multiple=Export Notes…
|
||||||
|
pane.items.menu.exportPDF=Export PDF…
|
||||||
|
pane.items.menu.exportPDF.multiple=Export PDFs…
|
||||||
pane.items.menu.createBib=Vytvořit bibliografii z vybrané položky...
|
pane.items.menu.createBib=Vytvořit bibliografii z vybrané položky...
|
||||||
pane.items.menu.createBib.multiple=Vytvořit bibliografii z vybraných položek...
|
pane.items.menu.createBib.multiple=Vytvořit bibliografii z vybraných položek...
|
||||||
pane.items.menu.generateReport=Vygenerovat zprávu z vybrané položky...
|
pane.items.menu.generateReport=Vygenerovat zprávu z vybrané položky...
|
||||||
|
|
@ -355,6 +362,8 @@ pane.items.menu.createParent=Create Parent Item…
|
||||||
pane.items.menu.createParent.multiple=Create Parent Items
|
pane.items.menu.createParent.multiple=Create Parent Items
|
||||||
pane.items.menu.renameAttachments=Přejmenovat soubor z rodičovských metadat
|
pane.items.menu.renameAttachments=Přejmenovat soubor z rodičovských metadat
|
||||||
pane.items.menu.renameAttachments.multiple=Přejmenovat soubory z rodičovských metadat
|
pane.items.menu.renameAttachments.multiple=Přejmenovat soubory z rodičovských metadat
|
||||||
|
pane.items.menu.duplicateAndConvert.toBookSection=Create Book Section
|
||||||
|
pane.items.menu.duplicateAndConvert.toBook=Create Book from Book Section
|
||||||
pane.items.showItemInLibrary=Zobrazit položku v Knihovně.
|
pane.items.showItemInLibrary=Zobrazit položku v Knihovně.
|
||||||
|
|
||||||
pane.items.letter.oneParticipant=Dopis pro %S
|
pane.items.letter.oneParticipant=Dopis pro %S
|
||||||
|
|
@ -393,7 +402,7 @@ pane.item.switchFieldMode.two=Přepnout na více polí
|
||||||
pane.item.creator.moveToTop=Přesunout nahoru
|
pane.item.creator.moveToTop=Přesunout nahoru
|
||||||
pane.item.creator.moveUp=Posunout nahoru
|
pane.item.creator.moveUp=Posunout nahoru
|
||||||
pane.item.creator.moveDown=Posunout dolů
|
pane.item.creator.moveDown=Posunout dolů
|
||||||
pane.item.notes.allNotes=All Notes
|
pane.item.notes.allNotes=Všechny poznámky
|
||||||
pane.item.notes.untitled=Nepojmenovaná poznámka
|
pane.item.notes.untitled=Nepojmenovaná poznámka
|
||||||
pane.item.notes.delete.confirm=Jste si jistý, že chcete smazat tuto poznámku?
|
pane.item.notes.delete.confirm=Jste si jistý, že chcete smazat tuto poznámku?
|
||||||
pane.item.notes.count=%1$S note;%1$S notes
|
pane.item.notes.count=%1$S note;%1$S notes
|
||||||
|
|
@ -408,6 +417,16 @@ pane.item.attachments.fileNotFound.text2.stored=Je možné, že byl přesunut ne
|
||||||
pane.item.attachments.fileNotFound.text2.stored.notOnServer=Je možné, že byl přesunut nebo smazán mimo %1$S, nebo, pokud byl tento soubor přidán na jiném počítači, je možné, že ještě nebyla provedena synchronizace do %2$S.
|
pane.item.attachments.fileNotFound.text2.stored.notOnServer=Je možné, že byl přesunut nebo smazán mimo %1$S, nebo, pokud byl tento soubor přidán na jiném počítači, je možné, že ještě nebyla provedena synchronizace do %2$S.
|
||||||
pane.item.attachments.fileNotFound.text2.linked=Je možné, že byl přesunut nebo smazán mimo %1$S nebo na vašem počítači není správně nastaven základní adresář pro připojené přílohy.
|
pane.item.attachments.fileNotFound.text2.linked=Je možné, že byl přesunut nebo smazán mimo %1$S nebo na vašem počítači není správně nastaven základní adresář pro připojené přílohy.
|
||||||
pane.item.attachments.delete.confirm=Jste si jisti, že chcete smazat tuto přílohu?
|
pane.item.attachments.delete.confirm=Jste si jisti, že chcete smazat tuto přílohu?
|
||||||
|
pane.item.attachments.autoRelink.title=File Located Automatically
|
||||||
|
pane.item.attachments.autoRelink.text1=The file could not be found at the specified location, but a file with the same name was found within your Linked Attachment Base Directory:
|
||||||
|
pane.item.attachments.autoRelink.text2=Old Location: %S
|
||||||
|
pane.item.attachments.autoRelink.text3=New Location: %S
|
||||||
|
pane.item.attachments.autoRelink.text4=%1$S can automatically relink this attachment.
|
||||||
|
pane.item.attachments.autoRelink.relink=Relink
|
||||||
|
pane.item.attachments.autoRelinkOthers.title=Additional Files Located
|
||||||
|
pane.item.attachments.autoRelinkOthers.text=One other unlinked attachment in this library was found within the same directory. Relink this attachment as well?;%S other unlinked attachments in this library were found within the same directory. Relink all located attachments?
|
||||||
|
pane.item.attachments.autoRelink.locateManually=Locate Manually…
|
||||||
|
pane.item.attachments.autoRelink.relinkAll=Relink All
|
||||||
pane.item.attachments.count.zero=%S příloh:
|
pane.item.attachments.count.zero=%S příloh:
|
||||||
pane.item.attachments.count.singular=%S příloha:
|
pane.item.attachments.count.singular=%S příloha:
|
||||||
pane.item.attachments.count.plural=%S příloh:
|
pane.item.attachments.count.plural=%S příloh:
|
||||||
|
|
@ -430,15 +449,15 @@ pane.item.related.count.zero=%S souvisejících:
|
||||||
pane.item.related.count.singular=%S související:
|
pane.item.related.count.singular=%S související:
|
||||||
pane.item.related.count.plural=%S souvisejících:
|
pane.item.related.count.plural=%S souvisejících:
|
||||||
pane.item.parentItem=Rodičovská položka:
|
pane.item.parentItem=Rodičovská položka:
|
||||||
pane.item.viewOnline.tooltip=Go to this item online
|
pane.item.viewOnline.tooltip=Přejít na tuto položku online
|
||||||
|
|
||||||
pane.context.noParent=No parent item
|
pane.context.noParent=No parent item
|
||||||
pane.context.itemNotes=Item Notes
|
pane.context.itemNotes=Item Notes
|
||||||
pane.context.allNotes=All Notes
|
pane.context.allNotes=Všechny poznámky
|
||||||
pane.context.noNotes=No notes
|
pane.context.noNotes=Žádné poznámky
|
||||||
|
|
||||||
itemTypes.note=Poznámka
|
itemTypes.note=Poznámka
|
||||||
itemTypes.annotation=Annotation
|
itemTypes.annotation=Anotace
|
||||||
itemTypes.attachment=Příloha
|
itemTypes.attachment=Příloha
|
||||||
itemTypes.book=Kniha
|
itemTypes.book=Kniha
|
||||||
itemTypes.bookSection=Kapitola knihy
|
itemTypes.bookSection=Kapitola knihy
|
||||||
|
|
@ -719,6 +738,7 @@ zotero.preferences.export.quickCopy.citationStyles=Citační styly
|
||||||
zotero.preferences.export.quickCopy.exportFormats=Formáty exportu
|
zotero.preferences.export.quickCopy.exportFormats=Formáty exportu
|
||||||
zotero.preferences.export.quickCopy.instructions=Rychlé kopírování vám umožní jednoduše kopírovat vybrané položky v daném formátu. Vybranou položku zkopírujete do schránky stisknutím %S nebo přetažením položek do textového pole v jiném programu.
|
zotero.preferences.export.quickCopy.instructions=Rychlé kopírování vám umožní jednoduše kopírovat vybrané položky v daném formátu. Vybranou položku zkopírujete do schránky stisknutím %S nebo přetažením položek do textového pole v jiném programu.
|
||||||
zotero.preferences.export.quickCopy.citationInstructions=U citačních stylů můžete kopírovat citace nebo poznámky pod čarou stisknutím %S nebo podržením klávesy Shift před přetažením položek.
|
zotero.preferences.export.quickCopy.citationInstructions=U citačních stylů můžete kopírovat citace nebo poznámky pod čarou stisknutím %S nebo podržením klávesy Shift před přetažením položek.
|
||||||
|
zotero.preferences.export.quickCopy.note.htmlOptions.label=Rich Text/HTML
|
||||||
|
|
||||||
zotero.preferences.wordProcessors.installationSuccess=Instalace proběhla úspěšně.
|
zotero.preferences.wordProcessors.installationSuccess=Instalace proběhla úspěšně.
|
||||||
zotero.preferences.wordProcessors.installationError=Instalace nemohla být dokončena, protože došlo k chybě. Prosím ujistěte se, že je %1$S zavřený a poté restartujte %2$S.
|
zotero.preferences.wordProcessors.installationError=Instalace nemohla být dokončena, protože došlo k chybě. Prosím ujistěte se, že je %1$S zavřený a poté restartujte %2$S.
|
||||||
|
|
@ -864,22 +884,7 @@ citation.showEditor=Zobrazit editor...
|
||||||
citation.hideEditor=Skrýt editor...
|
citation.hideEditor=Skrýt editor...
|
||||||
citation.citations=Citace
|
citation.citations=Citace
|
||||||
citation.notes=Poznámky
|
citation.notes=Poznámky
|
||||||
citation.locator.page=Stránka
|
citation.locator.timestamp=Timestamp
|
||||||
citation.locator.book=Kniha
|
|
||||||
citation.locator.chapter=Kapitola
|
|
||||||
citation.locator.column=Sloupec
|
|
||||||
citation.locator.figure=Obrázek
|
|
||||||
citation.locator.folio=Složka
|
|
||||||
citation.locator.issue=Číslo
|
|
||||||
citation.locator.line=Řádek
|
|
||||||
citation.locator.note=Poznámka
|
|
||||||
citation.locator.opus=Opus
|
|
||||||
citation.locator.paragraph=Odstavec
|
|
||||||
citation.locator.part=Část
|
|
||||||
citation.locator.section=Sekce
|
|
||||||
citation.locator.subverbo=Pod heslem
|
|
||||||
citation.locator.volume=Ročník
|
|
||||||
citation.locator.verse=Verš
|
|
||||||
|
|
||||||
report.title.default=Zotero report
|
report.title.default=Zotero report
|
||||||
report.parentItem=Rodičovská položka:
|
report.parentItem=Rodičovská položka:
|
||||||
|
|
@ -1005,7 +1010,7 @@ sync.skipGroup=Přeskočit skupinu
|
||||||
sync.removeGroupsAndSync=Odstranit skupinu a synchronizovat
|
sync.removeGroupsAndSync=Odstranit skupinu a synchronizovat
|
||||||
|
|
||||||
sync.reminder.setUp.message=Back up your library with %S syncing.
|
sync.reminder.setUp.message=Back up your library with %S syncing.
|
||||||
sync.reminder.setUp.action=Set Up Syncing
|
sync.reminder.setUp.action=Nastavení synchronizace
|
||||||
sync.reminder.autoSync.message=%S hasn’t synced in a while. Do you want to enable automatic syncing?
|
sync.reminder.autoSync.message=%S hasn’t synced in a while. Do you want to enable automatic syncing?
|
||||||
|
|
||||||
sync.error.usernameNotSet=Uživatelské jméno není nastaveno
|
sync.error.usernameNotSet=Uživatelské jméno není nastaveno
|
||||||
|
|
@ -1218,6 +1223,8 @@ locate.externalViewer.label=Otevřít v externí aplikaci
|
||||||
locate.internalViewer.label=Otevřít v interní prohlížečce
|
locate.internalViewer.label=Otevřít v interní prohlížečce
|
||||||
locate.showFile.label=Zobrazit soubor
|
locate.showFile.label=Zobrazit soubor
|
||||||
locate.libraryLookup.label=Hledat v knihovně
|
locate.libraryLookup.label=Hledat v knihovně
|
||||||
|
locate.libraryLookup.noResolver.title=No OpenURL Resolver
|
||||||
|
locate.libraryLookup.noResolver.text=You must choose an OpenURL resolver from the Advanced pane of the %S preferences.
|
||||||
locate.manageLocateEngines=Manage Lookup Engines...
|
locate.manageLocateEngines=Manage Lookup Engines...
|
||||||
locate.locateEngineDescription=Lookup engines help you find resources in your %S library on the web. Engines enabled in this list appear in the Locate drop-down in the toolbar.
|
locate.locateEngineDescription=Lookup engines help you find resources in your %S library on the web. Engines enabled in this list appear in the Locate drop-down in the toolbar.
|
||||||
|
|
||||||
|
|
@ -1293,9 +1300,9 @@ retraction.citationWarning=Ve vašem dokumentu byly odvoláno publikování cita
|
||||||
retraction.citationWarning.dontWarn=Varování k této položce mi příště nezobrazujte
|
retraction.citationWarning.dontWarn=Varování k této položce mi příště nezobrazujte
|
||||||
|
|
||||||
noteEditor.annotationsDateLine=(%S)
|
noteEditor.annotationsDateLine=(%S)
|
||||||
noteEditor.cut=Cut
|
noteEditor.cut=Vyjmout
|
||||||
noteEditor.copy=Copy
|
noteEditor.copy=Kopírovat
|
||||||
noteEditor.paste=Paste
|
noteEditor.paste=Vložit
|
||||||
noteEditor.rightToLeft=Right to Left
|
noteEditor.rightToLeft=Right to Left
|
||||||
noteEditor.leftToRight=Left to Right
|
noteEditor.leftToRight=Left to Right
|
||||||
noteEditor.updateNotice=This note was edited with a newer version of %1$S.\nPlease update %1$S to make changes.
|
noteEditor.updateNotice=This note was edited with a newer version of %1$S.\nPlease update %1$S to make changes.
|
||||||
|
|
@ -1303,21 +1310,22 @@ noteEditor.enterLink=Enter Link
|
||||||
noteEditor.heading1=Heading 1
|
noteEditor.heading1=Heading 1
|
||||||
noteEditor.heading2=Heading 2
|
noteEditor.heading2=Heading 2
|
||||||
noteEditor.heading3=Heading 3
|
noteEditor.heading3=Heading 3
|
||||||
noteEditor.paragraph=Paragraph
|
noteEditor.paragraph=Odstavec
|
||||||
noteEditor.monospaced=Monospaced
|
noteEditor.monospaced=Monospaced
|
||||||
noteEditor.bulletList=Bulleted List
|
noteEditor.bulletList=Bulleted List
|
||||||
noteEditor.orderedList=Numbered List
|
noteEditor.orderedList=Numbered List
|
||||||
noteEditor.blockquote=Block Quote
|
noteEditor.blockquote=Block Quote
|
||||||
|
noteEditor.mathBlock=Math Block
|
||||||
noteEditor.formatText=Format Text
|
noteEditor.formatText=Format Text
|
||||||
noteEditor.highlightText=Highlight Text
|
noteEditor.highlightText=Zvýraznit text
|
||||||
noteEditor.removeColor=Remove Color
|
noteEditor.removeColor=Odstranit barvu
|
||||||
noteEditor.bold=Bold
|
noteEditor.bold=Tučné
|
||||||
noteEditor.italic=Italic
|
noteEditor.italic=Kurzíva
|
||||||
noteEditor.underline=Underline
|
noteEditor.underline=Podtržené
|
||||||
noteEditor.strikethrough=Strikethrough
|
noteEditor.strikethrough=Strikethrough
|
||||||
noteEditor.subscript=Subscript
|
noteEditor.subscript=Spodní index
|
||||||
noteEditor.superscript=Superscript
|
noteEditor.superscript=Horní index
|
||||||
noteEditor.returnToNotesList=Return to Notes List
|
noteEditor.returnToNotesList=Návrat do seznamu poznámek
|
||||||
noteEditor.insertLink=Insert Link
|
noteEditor.insertLink=Insert Link
|
||||||
noteEditor.clearFormatting=Clear Formatting
|
noteEditor.clearFormatting=Clear Formatting
|
||||||
noteEditor.align=Align
|
noteEditor.align=Align
|
||||||
|
|
@ -1325,8 +1333,8 @@ noteEditor.alignLeft=Align Left
|
||||||
noteEditor.alignCenter=Align Center
|
noteEditor.alignCenter=Align Center
|
||||||
noteEditor.alignRight=Align Right
|
noteEditor.alignRight=Align Right
|
||||||
noteEditor.insertCitation=Insert Citation
|
noteEditor.insertCitation=Insert Citation
|
||||||
noteEditor.more=More
|
noteEditor.more=Více
|
||||||
noteEditor.find=Find
|
noteEditor.find=Najít
|
||||||
noteEditor.replace=Replace
|
noteEditor.replace=Replace
|
||||||
noteEditor.previous=Previous
|
noteEditor.previous=Previous
|
||||||
noteEditor.next=Next
|
noteEditor.next=Next
|
||||||
|
|
@ -1338,16 +1346,20 @@ noteEditor.editCitation=Edit Citation
|
||||||
noteEditor.showOnPage=Show on Page
|
noteEditor.showOnPage=Show on Page
|
||||||
noteEditor.unlink=Unlink
|
noteEditor.unlink=Unlink
|
||||||
noteEditor.set=Set
|
noteEditor.set=Set
|
||||||
noteEditor.edit=Edit
|
noteEditor.edit=Upravit
|
||||||
noteEditor.addCitation=Add Citation
|
noteEditor.addCitation=Add Citation
|
||||||
noteEditor.removeCitation=Hide Citation
|
noteEditor.removeCitation=Hide Citation
|
||||||
noteEditor.findAndReplace=Find and Replace
|
noteEditor.findAndReplace=Find and Replace
|
||||||
noteEditor.editInWindow=Edit in a Separate Window
|
noteEditor.editInWindow=Edit in a Separate Window
|
||||||
noteEditor.applyAnnotationColors=Show Annotation Colors
|
noteEditor.applyAnnotationColors=Zobrazit barvu anotací
|
||||||
noteEditor.removeAnnotationColors=Hide Annotation Colors
|
noteEditor.removeAnnotationColors=Skrýt barvu anotací
|
||||||
noteEditor.addCitations=Show Annotation Citations
|
noteEditor.addCitations=Show Annotation Citations
|
||||||
noteEditor.removeCitations=Hide Annotation Citations
|
noteEditor.removeCitations=Hide Annotation Citations
|
||||||
noteEditor.insertTable=Insert Table
|
noteEditor.image=Obrázek
|
||||||
|
noteEditor.math=Math
|
||||||
|
noteEditor.table=Table
|
||||||
|
noteEditor.copyImage=Copy Image
|
||||||
|
noteEditor.saveImageAs=Save Image As…
|
||||||
noteEditor.insertRowBefore=Insert Row Above
|
noteEditor.insertRowBefore=Insert Row Above
|
||||||
noteEditor.insertRowAfter=Insert Row Below
|
noteEditor.insertRowAfter=Insert Row Below
|
||||||
noteEditor.insertColumnBefore=Insert Column Left
|
noteEditor.insertColumnBefore=Insert Column Left
|
||||||
|
|
@ -1356,37 +1368,46 @@ noteEditor.deleteRow=Delete Row
|
||||||
noteEditor.deleteColumn=Delete Column
|
noteEditor.deleteColumn=Delete Column
|
||||||
noteEditor.deleteTable=Delete Table
|
noteEditor.deleteTable=Delete Table
|
||||||
|
|
||||||
pdfReader.annotations=Annotations
|
pdfReader.annotations=Anotace
|
||||||
pdfReader.showAnnotations=Show Annotations
|
pdfReader.showAnnotations=Zobrazit anotace
|
||||||
pdfReader.searchAnnotations=Search Annotations
|
pdfReader.searchAnnotations=Vyhledat anotace
|
||||||
pdfReader.noAnnotations=Create an annotation to see it in the sidebar
|
pdfReader.noAnnotations=Create an annotation to see it in the sidebar
|
||||||
pdfReader.addText=Add extracted text
|
pdfReader.noExtractedText=No extracted text
|
||||||
pdfReader.addComment=Add comment
|
pdfReader.addComment=Add comment
|
||||||
pdfReader.addTags=Add tags…
|
pdfReader.addTags=Add tags…
|
||||||
pdfReader.highlightText=Highlight Text
|
pdfReader.highlightText=Zvýraznit text
|
||||||
pdfReader.addNote=Add Note
|
pdfReader.addNote=Přidat poznámku
|
||||||
pdfReader.selectArea=Select Area
|
pdfReader.selectArea=Select Area
|
||||||
pdfReader.pickColor=Pick a Color
|
pdfReader.pickColor=Pick a Color
|
||||||
pdfReader.addToNote=Add to Note
|
pdfReader.addToNote=Přidat do poznámky
|
||||||
pdfReader.zoomIn=Zoom In
|
pdfReader.zoomIn=Zoom In
|
||||||
pdfReader.zoomOut=Zoom Out
|
pdfReader.zoomOut=Zoom Out
|
||||||
pdfReader.zoomAuto=Automatically Resize
|
pdfReader.zoomAuto=Automatically Resize
|
||||||
pdfReader.zoomPageWidth=Zoom to Page Width
|
pdfReader.zoomPageWidth=Zoom to Page Width
|
||||||
pdfReader.zoomPageHeight=Zoom to Page Height
|
pdfReader.zoomPageHeight=Zoom to Page Height
|
||||||
|
pdfReader.splitVertically=Split Vertically
|
||||||
|
pdfReader.splitHorizontally=Split Horizontally
|
||||||
pdfReader.nextPage=Next Page
|
pdfReader.nextPage=Next Page
|
||||||
pdfReader.previousPage=Previous Page
|
pdfReader.previousPage=Previous Page
|
||||||
pdfReader.page=Page
|
pdfReader.page=Stránka
|
||||||
pdfReader.readOnly=Read-only
|
pdfReader.readOnly=Read-only
|
||||||
pdfReader.promptTransferFromPDF.title=Import Annotations
|
pdfReader.promptTransferFromPDF.title=Importovat anotace
|
||||||
pdfReader.promptTransferFromPDF.text=Annotations stored in the PDF file will be moved to %1$S.
|
pdfReader.promptTransferFromPDF.text=Annotations stored in the PDF file will be moved to %1$S.
|
||||||
pdfReader.promptTransferToPDF.title=Store Annotations in File
|
pdfReader.promptTransferToPDF.title=Uložit anotace v souboru
|
||||||
pdfReader.promptTransferToPDF.text=Annotations will be transferred to the PDF file and will no longer be editable in %S.
|
pdfReader.promptTransferToPDF.text=Annotations will be transferred to the PDF file and will no longer be editable in %S.
|
||||||
pdfReader.promptPasswordProtected=The operation is not supported for password-protected PDF files.
|
pdfReader.promptPasswordProtected=The operation is not supported for password-protected PDF files.
|
||||||
|
pdfReader.promptDeletePages.title=Delete Pages
|
||||||
|
pdfReader.promptDeletePages.text=Are you sure you want to delete %1$S page from the PDF file?;Are you sure you want to delete %1$S pages from the PDF file?
|
||||||
|
pdfReader.rotateLeft=Rotate Left
|
||||||
|
pdfReader.rotateRight=Rotate Right
|
||||||
|
pdfReader.rotate180=Rotate 180°
|
||||||
pdfReader.editPageNumber=Edit Page Number…
|
pdfReader.editPageNumber=Edit Page Number…
|
||||||
pdfReader.editHighlightedText=Edit Highlighted Text
|
pdfReader.editHighlightedText=Edit Highlighted Text
|
||||||
|
pdfReader.copyImage=Copy Image
|
||||||
|
pdfReader.saveImageAs=Save Image As…
|
||||||
pdfReader.pageNumberPopupHeader=Change page number for:
|
pdfReader.pageNumberPopupHeader=Change page number for:
|
||||||
pdfReader.thisAnnotation=This annotation
|
pdfReader.thisAnnotation=Tato anotace
|
||||||
pdfReader.selectedAnnotations=Selected annotations
|
pdfReader.selectedAnnotations=Vybrané anotace
|
||||||
pdfReader.thisPage=This page
|
pdfReader.thisPage=This page
|
||||||
pdfReader.thisPageAndLaterPages=This page and later pages
|
pdfReader.thisPageAndLaterPages=This page and later pages
|
||||||
pdfReader.allPages=All pages
|
pdfReader.allPages=All pages
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,12 @@
|
||||||
"general_done": {
|
"general_done": {
|
||||||
"message": "Færdig"
|
"message": "Færdig"
|
||||||
},
|
},
|
||||||
|
"general_yes": {
|
||||||
|
"message": "Ja"
|
||||||
|
},
|
||||||
|
"general_no": {
|
||||||
|
"message": "Nej"
|
||||||
|
},
|
||||||
"general_tryAgain": {
|
"general_tryAgain": {
|
||||||
"message": "Prøv igen"
|
"message": "Prøv igen"
|
||||||
},
|
},
|
||||||
|
|
@ -14,6 +20,9 @@
|
||||||
"general_cancel": {
|
"general_cancel": {
|
||||||
"message": "Annullér"
|
"message": "Annullér"
|
||||||
},
|
},
|
||||||
|
"general_copyToClipboard": {
|
||||||
|
"message": "Kopiér til udklipsholderen"
|
||||||
|
},
|
||||||
"progressWindow_savingTo": {
|
"progressWindow_savingTo": {
|
||||||
"message": "Gemmer i"
|
"message": "Gemmer i"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,14 @@
|
||||||
<!ENTITY zotero.general.deselectAll "Fravælg alle">
|
<!ENTITY zotero.general.deselectAll "Fravælg alle">
|
||||||
<!ENTITY zotero.general.edit "Rediger">
|
<!ENTITY zotero.general.edit "Rediger">
|
||||||
<!ENTITY zotero.general.delete "Slet">
|
<!ENTITY zotero.general.delete "Slet">
|
||||||
<!ENTITY zotero.general.moveToTrash "Move to Trash">
|
<!ENTITY zotero.general.moveToTrash "Flyt til papirkurv">
|
||||||
<!ENTITY zotero.general.ok "OK">
|
<!ENTITY zotero.general.ok "OK">
|
||||||
<!ENTITY zotero.general.cancel "Annullér">
|
<!ENTITY zotero.general.cancel "Annullér">
|
||||||
<!ENTITY zotero.general.refresh "Opdatér">
|
<!ENTITY zotero.general.refresh "Opdatér">
|
||||||
<!ENTITY zotero.general.saveAs "Gem som...">
|
<!ENTITY zotero.general.saveAs "Gem som...">
|
||||||
<!ENTITY zotero.general.options "Indstillinger">
|
<!ENTITY zotero.general.options "Indstillinger">
|
||||||
<!ENTITY zotero.general.advancedOptions.label "Avancerede indstillinger">
|
<!ENTITY zotero.general.advancedOptions.label "Avancerede indstillinger">
|
||||||
<!ENTITY zotero.general.tools "Tools">
|
<!ENTITY zotero.general.tools "Værktøj">
|
||||||
<!ENTITY zotero.general.more "Mere">
|
<!ENTITY zotero.general.more "Mere">
|
||||||
<!ENTITY zotero.general.loading "Indlæser...">
|
<!ENTITY zotero.general.loading "Indlæser...">
|
||||||
<!ENTITY zotero.general.close "Luk">
|
<!ENTITY zotero.general.close "Luk">
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
<!ENTITY zotero.general.other "Andet...">
|
<!ENTITY zotero.general.other "Andet...">
|
||||||
<!ENTITY zotero.general.bigger "Bigger">
|
<!ENTITY zotero.general.bigger "Bigger">
|
||||||
<!ENTITY zotero.general.smaller "Smaller">
|
<!ENTITY zotero.general.smaller "Smaller">
|
||||||
<!ENTITY zotero.general.reset "Reset">
|
<!ENTITY zotero.general.reset "Nulstil">
|
||||||
|
|
||||||
|
|
||||||
<!ENTITY zotero.errorReport.title "Zotero fejlrapport">
|
<!ENTITY zotero.errorReport.title "Zotero fejlrapport">
|
||||||
|
|
@ -128,8 +128,8 @@
|
||||||
<!ENTITY zotero.toolbar.attachment.add "Gem kopi af filen...">
|
<!ENTITY zotero.toolbar.attachment.add "Gem kopi af filen...">
|
||||||
<!ENTITY zotero.toolbar.attachment.weblink "Gem link til den aktuelle side">
|
<!ENTITY zotero.toolbar.attachment.weblink "Gem link til den aktuelle side">
|
||||||
<!ENTITY zotero.toolbar.attachment.snapshot "Tag kopi af den aktuelle side">
|
<!ENTITY zotero.toolbar.attachment.snapshot "Tag kopi af den aktuelle side">
|
||||||
<!ENTITY zotero.toolbar.context.item "Item">
|
<!ENTITY zotero.toolbar.context.item "Element">
|
||||||
<!ENTITY zotero.toolbar.context.notes "Notes">
|
<!ENTITY zotero.toolbar.context.notes "Noter">
|
||||||
|
|
||||||
<!ENTITY zotero.tagSelector.noTagsToDisplay "Der er ingen mærker at vise">
|
<!ENTITY zotero.tagSelector.noTagsToDisplay "Der er ingen mærker at vise">
|
||||||
<!ENTITY zotero.tagSelector.loadingTags "Indlæser mærker...">
|
<!ENTITY zotero.tagSelector.loadingTags "Indlæser mærker...">
|
||||||
|
|
@ -150,7 +150,7 @@
|
||||||
<!ENTITY zotero.lookup.description "Enter ISBNs, DOIs, PMIDs, arXiv IDs, or ADS Bibcodes to add to your library:">
|
<!ENTITY zotero.lookup.description "Enter ISBNs, DOIs, PMIDs, arXiv IDs, or ADS Bibcodes to add to your library:">
|
||||||
<!ENTITY zotero.lookup.button.search "Søg">
|
<!ENTITY zotero.lookup.button.search "Søg">
|
||||||
|
|
||||||
<!ENTITY zotero.createParent.title "Create Parent Item">
|
<!ENTITY zotero.createParent.title "Opret moder-element">
|
||||||
<!ENTITY zotero.createParent.button.manual "Manual Entry">
|
<!ENTITY zotero.createParent.button.manual "Manual Entry">
|
||||||
|
|
||||||
<!ENTITY zotero.selectitems.title "Vælg elementer">
|
<!ENTITY zotero.selectitems.title "Vælg elementer">
|
||||||
|
|
@ -307,12 +307,10 @@
|
||||||
<!ENTITY zotero.context.addStandaloneNoteFromAnnotations "Add Standalone Note from Annotations">
|
<!ENTITY zotero.context.addStandaloneNoteFromAnnotations "Add Standalone Note from Annotations">
|
||||||
<!ENTITY zotero.context.editInWindow "Edit in a Separate Window">
|
<!ENTITY zotero.context.editInWindow "Edit in a Separate Window">
|
||||||
|
|
||||||
<!ENTITY zotero.pdfReader.firstPage "First Page">
|
<!ENTITY zotero.pdfReader.firstPage "Første side">
|
||||||
<!ENTITY zotero.pdfReader.lastPage "Last Page">
|
<!ENTITY zotero.pdfReader.lastPage "Last Page">
|
||||||
<!ENTITY zotero.pdfReader.back "Back">
|
<!ENTITY zotero.pdfReader.back "Back">
|
||||||
<!ENTITY zotero.pdfReader.forward "Forward">
|
<!ENTITY zotero.pdfReader.forward "Forward">
|
||||||
<!ENTITY zotero.pdfReader.rotateClockwise "Rotate Clockwise">
|
|
||||||
<!ENTITY zotero.pdfReader.rotateCounterclockwise "Rotate Counterclockwise">
|
|
||||||
<!ENTITY zotero.pdfReader.handTool "Hand Tool">
|
<!ENTITY zotero.pdfReader.handTool "Hand Tool">
|
||||||
<!ENTITY zotero.pdfReader.verticalScrolling "Vertical Scrolling">
|
<!ENTITY zotero.pdfReader.verticalScrolling "Vertical Scrolling">
|
||||||
<!ENTITY zotero.pdfReader.horizontalScrolling "Horizontal Scrolling">
|
<!ENTITY zotero.pdfReader.horizontalScrolling "Horizontal Scrolling">
|
||||||
|
|
@ -325,4 +323,9 @@
|
||||||
<!ENTITY zotero.pdfReader.zoomAuto "Automatically Resize">
|
<!ENTITY zotero.pdfReader.zoomAuto "Automatically Resize">
|
||||||
<!ENTITY zotero.pdfReader.zoomPageWidth "Zoom to Page Width">
|
<!ENTITY zotero.pdfReader.zoomPageWidth "Zoom to Page Width">
|
||||||
<!ENTITY zotero.pdfReader.zoomPageHeight "Zoom to Page Height">
|
<!ENTITY zotero.pdfReader.zoomPageHeight "Zoom to Page Height">
|
||||||
|
<!ENTITY zotero.pdfReader.splitVertically "Split Vertically">
|
||||||
|
<!ENTITY zotero.pdfReader.splitHorizontally "Split Horizontally">
|
||||||
<!ENTITY zotero.pdfReader.transferFromPDF "Import Annotations…">
|
<!ENTITY zotero.pdfReader.transferFromPDF "Import Annotations…">
|
||||||
|
<!ENTITY zotero.pdfReader.rotatePageLeft "Rotate Page Left">
|
||||||
|
<!ENTITY zotero.pdfReader.rotatePageRight "Rotate Page Right">
|
||||||
|
<!ENTITY zotero.pdfReader.rotatePage180 "Rotate Page 180°">
|
||||||
|
|
|
||||||
|
|
@ -45,14 +45,14 @@ general.character.plural=tegn
|
||||||
general.create=Opret
|
general.create=Opret
|
||||||
general.delete=Slet
|
general.delete=Slet
|
||||||
general.remove=Fjern
|
general.remove=Fjern
|
||||||
general.import=Import
|
general.import=Importér
|
||||||
general.export=Export
|
general.export=Eksportér
|
||||||
general.update=Update
|
general.update=Update
|
||||||
general.moreInformation=Mere information
|
general.moreInformation=Mere information
|
||||||
general.learnMore=Learn More
|
general.learnMore=Learn More
|
||||||
general.seeForMoreInformation=Se %S for nærmere oplysninger.
|
general.seeForMoreInformation=Se %S for nærmere oplysninger.
|
||||||
general.open=Åbn %S
|
general.open=Åbn %S
|
||||||
general.close=Close
|
general.close=Luk
|
||||||
general.enable=Slå til
|
general.enable=Slå til
|
||||||
general.disable=Slå fra
|
general.disable=Slå fra
|
||||||
general.reset=Nulstil
|
general.reset=Nulstil
|
||||||
|
|
@ -71,9 +71,9 @@ general.fix=Løs...
|
||||||
general.tryAgain=Prøv igen
|
general.tryAgain=Prøv igen
|
||||||
general.tryLater=Prøv igen senere
|
general.tryLater=Prøv igen senere
|
||||||
general.showDirectory=Vis mappe
|
general.showDirectory=Vis mappe
|
||||||
general.showInLibrary=Show in Library
|
general.showInLibrary=Vis i bibliotek
|
||||||
general.continue=Fortsæt
|
general.continue=Fortsæt
|
||||||
general.copy=Copy
|
general.copy=Kopier
|
||||||
general.copyToClipboard=Kopiér til udklipsholderen
|
general.copyToClipboard=Kopiér til udklipsholderen
|
||||||
general.cancel=Annullér
|
general.cancel=Annullér
|
||||||
general.clear=Ryd
|
general.clear=Ryd
|
||||||
|
|
@ -89,9 +89,10 @@ general.back=Back
|
||||||
general.languages=Languages
|
general.languages=Languages
|
||||||
general.default=Default
|
general.default=Default
|
||||||
general.custom=Custom
|
general.custom=Custom
|
||||||
general.loading=Loading…
|
general.loading=Indlæser...
|
||||||
general.richText=Rich Text
|
general.richText=Rich Text
|
||||||
general.clearSelection=Clear Selection
|
general.clearSelection=Clear Selection
|
||||||
|
general.insert=Insert
|
||||||
|
|
||||||
general.yellow=Yellow
|
general.yellow=Yellow
|
||||||
general.red=Red
|
general.red=Red
|
||||||
|
|
@ -114,6 +115,7 @@ about.getInvolved=Vil du hjælpe? [Bliv involveret] i dag!
|
||||||
punctuation.openingQMark=“
|
punctuation.openingQMark=“
|
||||||
punctuation.closingQMark=”
|
punctuation.closingQMark=”
|
||||||
punctuation.colon=:
|
punctuation.colon=:
|
||||||
|
punctuation.colon.withString=%S:
|
||||||
punctuation.ellipsis=...
|
punctuation.ellipsis=...
|
||||||
|
|
||||||
install.quickStartGuide=Kom hurtigt i gang med Zotero
|
install.quickStartGuide=Kom hurtigt i gang med Zotero
|
||||||
|
|
@ -327,8 +329,11 @@ pane.items.remove.multiple=Er du sikker på, du vil slette de valgte elementer f
|
||||||
pane.items.removeFromPublications.title=Fjern fra Mine publikationer
|
pane.items.removeFromPublications.title=Fjern fra Mine publikationer
|
||||||
pane.items.removeFromPublications=Er du sikker på, du vil slette det valgte element fra Mine publikationer?
|
pane.items.removeFromPublications=Er du sikker på, du vil slette det valgte element fra Mine publikationer?
|
||||||
pane.items.removeFromPublications.multiple=Er du sikker på, du vil slette det valgte element fra Mine publikationer?
|
pane.items.removeFromPublications.multiple=Er du sikker på, du vil slette det valgte element fra Mine publikationer?
|
||||||
|
pane.items.removeRecursive.title=Remove from Collection and Subcollections
|
||||||
|
pane.items.removeRecursive=Are you sure you want to remove the selected item from this collection and all subcollections?
|
||||||
|
pane.items.removeRecursive.multiple=Are you sure you want to remove the selected items from this collection and all subcollections?
|
||||||
pane.items.menu.addNoteFromAnnotations=Add Note from Annotations
|
pane.items.menu.addNoteFromAnnotations=Add Note from Annotations
|
||||||
pane.items.menu.addNoteFromAnnotations.multiple=Add Notes from Annotations
|
pane.items.menu.createNoteFromAnnotations=Create Note from Annotations
|
||||||
pane.items.menu.findAvailablePDF=Find tilgængelig PDF
|
pane.items.menu.findAvailablePDF=Find tilgængelig PDF
|
||||||
pane.items.menu.findAvailablePDF.multiple=Find tilgængelige PDF'er
|
pane.items.menu.findAvailablePDF.multiple=Find tilgængelige PDF'er
|
||||||
pane.items.menu.addToCollection=Add to Collection
|
pane.items.menu.addToCollection=Add to Collection
|
||||||
|
|
@ -338,11 +343,13 @@ pane.items.menu.removeFromPublications=Fjern element fra Mine publikationer...
|
||||||
pane.items.menu.removeFromPublications.multiple=Fjern elementer fra Mine publikationer...
|
pane.items.menu.removeFromPublications.multiple=Fjern elementer fra Mine publikationer...
|
||||||
pane.items.menu.moveToTrash=Flyt element til papirkurven...
|
pane.items.menu.moveToTrash=Flyt element til papirkurven...
|
||||||
pane.items.menu.moveToTrash.multiple=Flyt elementer til papirkurven...
|
pane.items.menu.moveToTrash.multiple=Flyt elementer til papirkurven...
|
||||||
pane.items.menu.delete=Delete Permanently…
|
pane.items.menu.delete=Slet permanent...
|
||||||
pane.items.menu.export=Eksportér dette element...
|
pane.items.menu.export=Eksportér dette element...
|
||||||
pane.items.menu.export.multiple=Eksportér disse elementer...
|
pane.items.menu.export.multiple=Eksportér disse elementer...
|
||||||
pane.items.menu.exportNote=Export Note…
|
pane.items.menu.exportNote=Export Note…
|
||||||
pane.items.menu.exportNote.multiple=Export Notes…
|
pane.items.menu.exportNote.multiple=Export Notes…
|
||||||
|
pane.items.menu.exportPDF=Export PDF…
|
||||||
|
pane.items.menu.exportPDF.multiple=Export PDFs…
|
||||||
pane.items.menu.createBib=Dan en referenceliste ud fra element...
|
pane.items.menu.createBib=Dan en referenceliste ud fra element...
|
||||||
pane.items.menu.createBib.multiple=Dan en referenceliste ud fra elementer...
|
pane.items.menu.createBib.multiple=Dan en referenceliste ud fra elementer...
|
||||||
pane.items.menu.generateReport=Opret rapport ud fra element...
|
pane.items.menu.generateReport=Opret rapport ud fra element...
|
||||||
|
|
@ -352,9 +359,11 @@ pane.items.menu.reindexItem.multiple=Indeksér elementer igen
|
||||||
pane.items.menu.recognizePDF=Hent metadata for pdf-filen.
|
pane.items.menu.recognizePDF=Hent metadata for pdf-filen.
|
||||||
pane.items.menu.recognizePDF.multiple=Hent metadata for pdf-filerne
|
pane.items.menu.recognizePDF.multiple=Hent metadata for pdf-filerne
|
||||||
pane.items.menu.createParent=Create Parent Item…
|
pane.items.menu.createParent=Create Parent Item…
|
||||||
pane.items.menu.createParent.multiple=Create Parent Items
|
pane.items.menu.createParent.multiple=Opret moder-elementer
|
||||||
pane.items.menu.renameAttachments=Omdøb fil fra moder-metadata
|
pane.items.menu.renameAttachments=Omdøb fil fra moder-metadata
|
||||||
pane.items.menu.renameAttachments.multiple=Omdøb filer fra moder-metadata
|
pane.items.menu.renameAttachments.multiple=Omdøb filer fra moder-metadata
|
||||||
|
pane.items.menu.duplicateAndConvert.toBookSection=Create Book Section
|
||||||
|
pane.items.menu.duplicateAndConvert.toBook=Create Book from Book Section
|
||||||
pane.items.showItemInLibrary=Vis element i Bibliotek
|
pane.items.showItemInLibrary=Vis element i Bibliotek
|
||||||
|
|
||||||
pane.items.letter.oneParticipant=Brev til %S
|
pane.items.letter.oneParticipant=Brev til %S
|
||||||
|
|
@ -404,10 +413,20 @@ pane.item.attachments.rename.error=Der opstod en fejl under omdøbningen af file
|
||||||
pane.item.attachments.fileNotFound.title=Fil ikke fundet
|
pane.item.attachments.fileNotFound.title=Fil ikke fundet
|
||||||
pane.item.attachments.fileNotFound.text1=Den vedhæftede fil kunne ikke findes.
|
pane.item.attachments.fileNotFound.text1=Den vedhæftede fil kunne ikke findes.
|
||||||
pane.item.attachments.fileNotFound.text1.path=The attached file could not be found at the following path:
|
pane.item.attachments.fileNotFound.text1.path=The attached file could not be found at the following path:
|
||||||
pane.item.attachments.fileNotFound.text2.stored=It may have been moved or deleted outside of %1$S, or, if the file was added on another computer, it may not yet have been synced to or from %2$S.
|
pane.item.attachments.fileNotFound.text2.stored=Den kan være blevet slettet eller flyttet uden for %1$S eller, hvis filen blev tilføjet på en anden computer, er den måske endnu ikke blevet synkroniseret til eller fra %2$S.
|
||||||
pane.item.attachments.fileNotFound.text2.stored.notOnServer=It may have been moved or deleted outside of %1$S, or, if the file was added on another computer, it may not yet have been synced to %2$S.
|
pane.item.attachments.fileNotFound.text2.stored.notOnServer=Den kan være blevet slettet eller flyttet uden for %1$S eller, hvis filen blev tilføjet på en anden computer, er den måske endnu ikke blevet synkroniseret til eller fra %2$S.
|
||||||
pane.item.attachments.fileNotFound.text2.linked=It may have been moved or deleted outside of %1$S, or a Linked Attachment Base Directory may be set incorrectly on one of your computers.
|
pane.item.attachments.fileNotFound.text2.linked=It may have been moved or deleted outside of %1$S, or a Linked Attachment Base Directory may be set incorrectly on one of your computers.
|
||||||
pane.item.attachments.delete.confirm=Er du sikker på, du vil slette denne vedhæftning ?
|
pane.item.attachments.delete.confirm=Er du sikker på, du vil slette denne vedhæftning ?
|
||||||
|
pane.item.attachments.autoRelink.title=File Located Automatically
|
||||||
|
pane.item.attachments.autoRelink.text1=The file could not be found at the specified location, but a file with the same name was found within your Linked Attachment Base Directory:
|
||||||
|
pane.item.attachments.autoRelink.text2=Old Location: %S
|
||||||
|
pane.item.attachments.autoRelink.text3=New Location: %S
|
||||||
|
pane.item.attachments.autoRelink.text4=%1$S can automatically relink this attachment.
|
||||||
|
pane.item.attachments.autoRelink.relink=Relink
|
||||||
|
pane.item.attachments.autoRelinkOthers.title=Additional Files Located
|
||||||
|
pane.item.attachments.autoRelinkOthers.text=One other unlinked attachment in this library was found within the same directory. Relink this attachment as well?;%S other unlinked attachments in this library were found within the same directory. Relink all located attachments?
|
||||||
|
pane.item.attachments.autoRelink.locateManually=Locate Manually…
|
||||||
|
pane.item.attachments.autoRelink.relinkAll=Relink All
|
||||||
pane.item.attachments.count.zero=%S vedhæftninger:
|
pane.item.attachments.count.zero=%S vedhæftninger:
|
||||||
pane.item.attachments.count.singular=%S vedhæftning:
|
pane.item.attachments.count.singular=%S vedhæftning:
|
||||||
pane.item.attachments.count.plural=%S vedhæftninger:
|
pane.item.attachments.count.plural=%S vedhæftninger:
|
||||||
|
|
@ -430,7 +449,7 @@ pane.item.related.count.zero=%S relaterede:
|
||||||
pane.item.related.count.singular=%S relateret:
|
pane.item.related.count.singular=%S relateret:
|
||||||
pane.item.related.count.plural=%S relaterede:
|
pane.item.related.count.plural=%S relaterede:
|
||||||
pane.item.parentItem=Overordnet element:
|
pane.item.parentItem=Overordnet element:
|
||||||
pane.item.viewOnline.tooltip=Go to this item online
|
pane.item.viewOnline.tooltip=Gå til dette element online
|
||||||
|
|
||||||
pane.context.noParent=No parent item
|
pane.context.noParent=No parent item
|
||||||
pane.context.itemNotes=Item Notes
|
pane.context.itemNotes=Item Notes
|
||||||
|
|
@ -438,7 +457,7 @@ pane.context.allNotes=All Notes
|
||||||
pane.context.noNotes=No notes
|
pane.context.noNotes=No notes
|
||||||
|
|
||||||
itemTypes.note=Note
|
itemTypes.note=Note
|
||||||
itemTypes.annotation=Annotation
|
itemTypes.annotation=Annotering
|
||||||
itemTypes.attachment=Vedhæftning
|
itemTypes.attachment=Vedhæftning
|
||||||
itemTypes.book=Bog
|
itemTypes.book=Bog
|
||||||
itemTypes.bookSection=Bidrag til bog
|
itemTypes.bookSection=Bidrag til bog
|
||||||
|
|
@ -719,6 +738,7 @@ zotero.preferences.export.quickCopy.citationStyles=Referenceformater
|
||||||
zotero.preferences.export.quickCopy.exportFormats=Eksport-formater
|
zotero.preferences.export.quickCopy.exportFormats=Eksport-formater
|
||||||
zotero.preferences.export.quickCopy.instructions=Med hurtigkopiering kan du eksportere elementer i et givent format. Du kan kopiere valgte elementer til udklipsholderen ved at trykke %S eller trække dem til en tekstboks i et andet program.
|
zotero.preferences.export.quickCopy.instructions=Med hurtigkopiering kan du eksportere elementer i et givent format. Du kan kopiere valgte elementer til udklipsholderen ved at trykke %S eller trække dem til en tekstboks i et andet program.
|
||||||
zotero.preferences.export.quickCopy.citationInstructions=I referenceformater kan du kopiere henvisninger og fodnoter ved at trykke %S eller holde Skift nede, før du trækker elementer.
|
zotero.preferences.export.quickCopy.citationInstructions=I referenceformater kan du kopiere henvisninger og fodnoter ved at trykke %S eller holde Skift nede, før du trækker elementer.
|
||||||
|
zotero.preferences.export.quickCopy.note.htmlOptions.label=Rich Text/HTML
|
||||||
|
|
||||||
zotero.preferences.wordProcessors.installationSuccess=Installationen gennemført.
|
zotero.preferences.wordProcessors.installationSuccess=Installationen gennemført.
|
||||||
zotero.preferences.wordProcessors.installationError=Installationen kunne ikke gennemføres, fordi der opstod en fejl. Sikr dig venligst, at %1$S er lukket og genstart %2$S.
|
zotero.preferences.wordProcessors.installationError=Installationen kunne ikke gennemføres, fordi der opstod en fejl. Sikr dig venligst, at %1$S er lukket og genstart %2$S.
|
||||||
|
|
@ -864,22 +884,7 @@ citation.showEditor=Vis redaktør...
|
||||||
citation.hideEditor=Skjul redaktør...
|
citation.hideEditor=Skjul redaktør...
|
||||||
citation.citations=Henvisninger
|
citation.citations=Henvisninger
|
||||||
citation.notes=Noter
|
citation.notes=Noter
|
||||||
citation.locator.page=Side
|
citation.locator.timestamp=Timestamp
|
||||||
citation.locator.book=Bog
|
|
||||||
citation.locator.chapter=Kapitel
|
|
||||||
citation.locator.column=Spalte
|
|
||||||
citation.locator.figure=Figur
|
|
||||||
citation.locator.folio=Folio
|
|
||||||
citation.locator.issue=Nummer
|
|
||||||
citation.locator.line=Linje
|
|
||||||
citation.locator.note=Note
|
|
||||||
citation.locator.opus=Værk
|
|
||||||
citation.locator.paragraph=Afsnit
|
|
||||||
citation.locator.part=Del
|
|
||||||
citation.locator.section=Afsnit
|
|
||||||
citation.locator.subverbo=Under ordet
|
|
||||||
citation.locator.volume=Bind
|
|
||||||
citation.locator.verse=Vers
|
|
||||||
|
|
||||||
report.title.default=Zotero-rapport
|
report.title.default=Zotero-rapport
|
||||||
report.parentItem=Overordnet element:
|
report.parentItem=Overordnet element:
|
||||||
|
|
@ -1005,7 +1010,7 @@ sync.skipGroup=Spring gruppe over
|
||||||
sync.removeGroupsAndSync=Fjern grupper og synkronisering
|
sync.removeGroupsAndSync=Fjern grupper og synkronisering
|
||||||
|
|
||||||
sync.reminder.setUp.message=Back up your library with %S syncing.
|
sync.reminder.setUp.message=Back up your library with %S syncing.
|
||||||
sync.reminder.setUp.action=Set Up Syncing
|
sync.reminder.setUp.action=Indstil synkronisering
|
||||||
sync.reminder.autoSync.message=%S hasn’t synced in a while. Do you want to enable automatic syncing?
|
sync.reminder.autoSync.message=%S hasn’t synced in a while. Do you want to enable automatic syncing?
|
||||||
|
|
||||||
sync.error.usernameNotSet=Brugernavn ikke angivet
|
sync.error.usernameNotSet=Brugernavn ikke angivet
|
||||||
|
|
@ -1218,6 +1223,8 @@ locate.externalViewer.label=Åbn i ekstern fremviser
|
||||||
locate.internalViewer.label=Åbn i intern fremviser
|
locate.internalViewer.label=Åbn i intern fremviser
|
||||||
locate.showFile.label=Vis fil
|
locate.showFile.label=Vis fil
|
||||||
locate.libraryLookup.label=Opslag i bibliotekskatalogen
|
locate.libraryLookup.label=Opslag i bibliotekskatalogen
|
||||||
|
locate.libraryLookup.noResolver.title=No OpenURL Resolver
|
||||||
|
locate.libraryLookup.noResolver.text=You must choose an OpenURL resolver from the Advanced pane of the %S preferences.
|
||||||
locate.manageLocateEngines=Håndtér søgemaskiner...
|
locate.manageLocateEngines=Håndtér søgemaskiner...
|
||||||
locate.locateEngineDescription=Lookup engines help you find resources in your %S library on the web. Engines enabled in this list appear in the Locate drop-down in the toolbar.
|
locate.locateEngineDescription=Lookup engines help you find resources in your %S library on the web. Engines enabled in this list appear in the Locate drop-down in the toolbar.
|
||||||
|
|
||||||
|
|
@ -1293,9 +1300,9 @@ retraction.citationWarning=A citation in your document has been retracted:
|
||||||
retraction.citationWarning.dontWarn=Don’t warn me about this item again
|
retraction.citationWarning.dontWarn=Don’t warn me about this item again
|
||||||
|
|
||||||
noteEditor.annotationsDateLine=(%S)
|
noteEditor.annotationsDateLine=(%S)
|
||||||
noteEditor.cut=Cut
|
noteEditor.cut=Klip
|
||||||
noteEditor.copy=Copy
|
noteEditor.copy=Kopier
|
||||||
noteEditor.paste=Paste
|
noteEditor.paste=Indsæt
|
||||||
noteEditor.rightToLeft=Right to Left
|
noteEditor.rightToLeft=Right to Left
|
||||||
noteEditor.leftToRight=Left to Right
|
noteEditor.leftToRight=Left to Right
|
||||||
noteEditor.updateNotice=This note was edited with a newer version of %1$S.\nPlease update %1$S to make changes.
|
noteEditor.updateNotice=This note was edited with a newer version of %1$S.\nPlease update %1$S to make changes.
|
||||||
|
|
@ -1303,20 +1310,21 @@ noteEditor.enterLink=Enter Link
|
||||||
noteEditor.heading1=Heading 1
|
noteEditor.heading1=Heading 1
|
||||||
noteEditor.heading2=Heading 2
|
noteEditor.heading2=Heading 2
|
||||||
noteEditor.heading3=Heading 3
|
noteEditor.heading3=Heading 3
|
||||||
noteEditor.paragraph=Paragraph
|
noteEditor.paragraph=Afsnit
|
||||||
noteEditor.monospaced=Monospaced
|
noteEditor.monospaced=Monospaced
|
||||||
noteEditor.bulletList=Bulleted List
|
noteEditor.bulletList=Bulleted List
|
||||||
noteEditor.orderedList=Numbered List
|
noteEditor.orderedList=Numbered List
|
||||||
noteEditor.blockquote=Block Quote
|
noteEditor.blockquote=Block Quote
|
||||||
|
noteEditor.mathBlock=Math Block
|
||||||
noteEditor.formatText=Format Text
|
noteEditor.formatText=Format Text
|
||||||
noteEditor.highlightText=Highlight Text
|
noteEditor.highlightText=Marker tekst
|
||||||
noteEditor.removeColor=Remove Color
|
noteEditor.removeColor=Fjern farve
|
||||||
noteEditor.bold=Bold
|
noteEditor.bold=Fed
|
||||||
noteEditor.italic=Italic
|
noteEditor.italic=Kursiv
|
||||||
noteEditor.underline=Underline
|
noteEditor.underline=Understreg
|
||||||
noteEditor.strikethrough=Strikethrough
|
noteEditor.strikethrough=Strikethrough
|
||||||
noteEditor.subscript=Subscript
|
noteEditor.subscript=Sænket skrift
|
||||||
noteEditor.superscript=Superscript
|
noteEditor.superscript=Hævet skrift
|
||||||
noteEditor.returnToNotesList=Return to Notes List
|
noteEditor.returnToNotesList=Return to Notes List
|
||||||
noteEditor.insertLink=Insert Link
|
noteEditor.insertLink=Insert Link
|
||||||
noteEditor.clearFormatting=Clear Formatting
|
noteEditor.clearFormatting=Clear Formatting
|
||||||
|
|
@ -1325,7 +1333,7 @@ noteEditor.alignLeft=Align Left
|
||||||
noteEditor.alignCenter=Align Center
|
noteEditor.alignCenter=Align Center
|
||||||
noteEditor.alignRight=Align Right
|
noteEditor.alignRight=Align Right
|
||||||
noteEditor.insertCitation=Insert Citation
|
noteEditor.insertCitation=Insert Citation
|
||||||
noteEditor.more=More
|
noteEditor.more=Mere
|
||||||
noteEditor.find=Find
|
noteEditor.find=Find
|
||||||
noteEditor.replace=Replace
|
noteEditor.replace=Replace
|
||||||
noteEditor.previous=Previous
|
noteEditor.previous=Previous
|
||||||
|
|
@ -1338,7 +1346,7 @@ noteEditor.editCitation=Edit Citation
|
||||||
noteEditor.showOnPage=Show on Page
|
noteEditor.showOnPage=Show on Page
|
||||||
noteEditor.unlink=Unlink
|
noteEditor.unlink=Unlink
|
||||||
noteEditor.set=Set
|
noteEditor.set=Set
|
||||||
noteEditor.edit=Edit
|
noteEditor.edit=Rediger
|
||||||
noteEditor.addCitation=Add Citation
|
noteEditor.addCitation=Add Citation
|
||||||
noteEditor.removeCitation=Hide Citation
|
noteEditor.removeCitation=Hide Citation
|
||||||
noteEditor.findAndReplace=Find and Replace
|
noteEditor.findAndReplace=Find and Replace
|
||||||
|
|
@ -1347,7 +1355,11 @@ noteEditor.applyAnnotationColors=Show Annotation Colors
|
||||||
noteEditor.removeAnnotationColors=Hide Annotation Colors
|
noteEditor.removeAnnotationColors=Hide Annotation Colors
|
||||||
noteEditor.addCitations=Show Annotation Citations
|
noteEditor.addCitations=Show Annotation Citations
|
||||||
noteEditor.removeCitations=Hide Annotation Citations
|
noteEditor.removeCitations=Hide Annotation Citations
|
||||||
noteEditor.insertTable=Insert Table
|
noteEditor.image=Grafik
|
||||||
|
noteEditor.math=Math
|
||||||
|
noteEditor.table=Table
|
||||||
|
noteEditor.copyImage=Copy Image
|
||||||
|
noteEditor.saveImageAs=Save Image As…
|
||||||
noteEditor.insertRowBefore=Insert Row Above
|
noteEditor.insertRowBefore=Insert Row Above
|
||||||
noteEditor.insertRowAfter=Insert Row Below
|
noteEditor.insertRowAfter=Insert Row Below
|
||||||
noteEditor.insertColumnBefore=Insert Column Left
|
noteEditor.insertColumnBefore=Insert Column Left
|
||||||
|
|
@ -1360,11 +1372,11 @@ pdfReader.annotations=Annotations
|
||||||
pdfReader.showAnnotations=Show Annotations
|
pdfReader.showAnnotations=Show Annotations
|
||||||
pdfReader.searchAnnotations=Search Annotations
|
pdfReader.searchAnnotations=Search Annotations
|
||||||
pdfReader.noAnnotations=Create an annotation to see it in the sidebar
|
pdfReader.noAnnotations=Create an annotation to see it in the sidebar
|
||||||
pdfReader.addText=Add extracted text
|
pdfReader.noExtractedText=No extracted text
|
||||||
pdfReader.addComment=Add comment
|
pdfReader.addComment=Add comment
|
||||||
pdfReader.addTags=Add tags…
|
pdfReader.addTags=Add tags…
|
||||||
pdfReader.highlightText=Highlight Text
|
pdfReader.highlightText=Marker tekst
|
||||||
pdfReader.addNote=Add Note
|
pdfReader.addNote=Tilføj note
|
||||||
pdfReader.selectArea=Select Area
|
pdfReader.selectArea=Select Area
|
||||||
pdfReader.pickColor=Pick a Color
|
pdfReader.pickColor=Pick a Color
|
||||||
pdfReader.addToNote=Add to Note
|
pdfReader.addToNote=Add to Note
|
||||||
|
|
@ -1373,17 +1385,26 @@ pdfReader.zoomOut=Zoom Out
|
||||||
pdfReader.zoomAuto=Automatically Resize
|
pdfReader.zoomAuto=Automatically Resize
|
||||||
pdfReader.zoomPageWidth=Zoom to Page Width
|
pdfReader.zoomPageWidth=Zoom to Page Width
|
||||||
pdfReader.zoomPageHeight=Zoom to Page Height
|
pdfReader.zoomPageHeight=Zoom to Page Height
|
||||||
|
pdfReader.splitVertically=Split Vertically
|
||||||
|
pdfReader.splitHorizontally=Split Horizontally
|
||||||
pdfReader.nextPage=Next Page
|
pdfReader.nextPage=Next Page
|
||||||
pdfReader.previousPage=Previous Page
|
pdfReader.previousPage=Previous Page
|
||||||
pdfReader.page=Page
|
pdfReader.page=Side
|
||||||
pdfReader.readOnly=Read-only
|
pdfReader.readOnly=Read-only
|
||||||
pdfReader.promptTransferFromPDF.title=Import Annotations
|
pdfReader.promptTransferFromPDF.title=Import Annotations
|
||||||
pdfReader.promptTransferFromPDF.text=Annotations stored in the PDF file will be moved to %1$S.
|
pdfReader.promptTransferFromPDF.text=Annotations stored in the PDF file will be moved to %1$S.
|
||||||
pdfReader.promptTransferToPDF.title=Store Annotations in File
|
pdfReader.promptTransferToPDF.title=Store Annotations in File
|
||||||
pdfReader.promptTransferToPDF.text=Annotations will be transferred to the PDF file and will no longer be editable in %S.
|
pdfReader.promptTransferToPDF.text=Annotations will be transferred to the PDF file and will no longer be editable in %S.
|
||||||
pdfReader.promptPasswordProtected=The operation is not supported for password-protected PDF files.
|
pdfReader.promptPasswordProtected=The operation is not supported for password-protected PDF files.
|
||||||
|
pdfReader.promptDeletePages.title=Delete Pages
|
||||||
|
pdfReader.promptDeletePages.text=Are you sure you want to delete %1$S page from the PDF file?;Are you sure you want to delete %1$S pages from the PDF file?
|
||||||
|
pdfReader.rotateLeft=Rotate Left
|
||||||
|
pdfReader.rotateRight=Rotate Right
|
||||||
|
pdfReader.rotate180=Rotate 180°
|
||||||
pdfReader.editPageNumber=Edit Page Number…
|
pdfReader.editPageNumber=Edit Page Number…
|
||||||
pdfReader.editHighlightedText=Edit Highlighted Text
|
pdfReader.editHighlightedText=Edit Highlighted Text
|
||||||
|
pdfReader.copyImage=Copy Image
|
||||||
|
pdfReader.saveImageAs=Save Image As…
|
||||||
pdfReader.pageNumberPopupHeader=Change page number for:
|
pdfReader.pageNumberPopupHeader=Change page number for:
|
||||||
pdfReader.thisAnnotation=This annotation
|
pdfReader.thisAnnotation=This annotation
|
||||||
pdfReader.selectedAnnotations=Selected annotations
|
pdfReader.selectedAnnotations=Selected annotations
|
||||||
|
|
|
||||||
|
|
@ -301,18 +301,16 @@
|
||||||
<!ENTITY zotero.attachLink.label.link "Link:">
|
<!ENTITY zotero.attachLink.label.link "Link:">
|
||||||
<!ENTITY zotero.attachLink.label.title "Titel:">
|
<!ENTITY zotero.attachLink.label.title "Titel:">
|
||||||
|
|
||||||
<!ENTITY zotero.context.addChildNote "Notiz zum Eintrag hinzufügen">
|
<!ENTITY zotero.context.addChildNote "Eintragsnotiz hinzufügen">
|
||||||
<!ENTITY zotero.context.addChildNoteFromAnnotations "Aus Annotationen Notiz zum Eintrag hinzufügen">
|
<!ENTITY zotero.context.addChildNoteFromAnnotations "Eintragsnotiz aus Anmerkungen hinzufügen">
|
||||||
<!ENTITY zotero.context.addStandaloneNote "Eigenständige Notiz hinzufügen">
|
<!ENTITY zotero.context.addStandaloneNote "Eigenständige Notiz hinzufügen">
|
||||||
<!ENTITY zotero.context.addStandaloneNoteFromAnnotations "Aus Annotationen eigenständige Notiz hinzufügen">
|
<!ENTITY zotero.context.addStandaloneNoteFromAnnotations "Eigenständige Notiz aus Anmerkungen hinzufügen">
|
||||||
<!ENTITY zotero.context.editInWindow "In einem neuen Fenster bearbeiten">
|
<!ENTITY zotero.context.editInWindow "In einem neuen Fenster bearbeiten">
|
||||||
|
|
||||||
<!ENTITY zotero.pdfReader.firstPage "Erste Seite">
|
<!ENTITY zotero.pdfReader.firstPage "Erste Seite">
|
||||||
<!ENTITY zotero.pdfReader.lastPage "Letzte Seite">
|
<!ENTITY zotero.pdfReader.lastPage "Letzte Seite">
|
||||||
<!ENTITY zotero.pdfReader.back "Zurück">
|
<!ENTITY zotero.pdfReader.back "Zurück">
|
||||||
<!ENTITY zotero.pdfReader.forward "Vorwärts">
|
<!ENTITY zotero.pdfReader.forward "Vorwärts">
|
||||||
<!ENTITY zotero.pdfReader.rotateClockwise "Drehe im Uhrzeigersinn">
|
|
||||||
<!ENTITY zotero.pdfReader.rotateCounterclockwise "Drehe gegen den Uhrzeigersinn">
|
|
||||||
<!ENTITY zotero.pdfReader.handTool "Hand-Werkzeug">
|
<!ENTITY zotero.pdfReader.handTool "Hand-Werkzeug">
|
||||||
<!ENTITY zotero.pdfReader.verticalScrolling "Vertikale Seitenanordnung">
|
<!ENTITY zotero.pdfReader.verticalScrolling "Vertikale Seitenanordnung">
|
||||||
<!ENTITY zotero.pdfReader.horizontalScrolling "Horizontale Seitenanordnung">
|
<!ENTITY zotero.pdfReader.horizontalScrolling "Horizontale Seitenanordnung">
|
||||||
|
|
@ -325,4 +323,9 @@
|
||||||
<!ENTITY zotero.pdfReader.zoomAuto "Automatisch Größe anpassen">
|
<!ENTITY zotero.pdfReader.zoomAuto "Automatisch Größe anpassen">
|
||||||
<!ENTITY zotero.pdfReader.zoomPageWidth "Auf Fensterbreite skalieren">
|
<!ENTITY zotero.pdfReader.zoomPageWidth "Auf Fensterbreite skalieren">
|
||||||
<!ENTITY zotero.pdfReader.zoomPageHeight "Auf Fensterhöhe skalieren">
|
<!ENTITY zotero.pdfReader.zoomPageHeight "Auf Fensterhöhe skalieren">
|
||||||
|
<!ENTITY zotero.pdfReader.splitVertically "Vertikal aufteilen">
|
||||||
|
<!ENTITY zotero.pdfReader.splitHorizontally "Horizontal aufteilen">
|
||||||
<!ENTITY zotero.pdfReader.transferFromPDF "Anmerkungen importieren…">
|
<!ENTITY zotero.pdfReader.transferFromPDF "Anmerkungen importieren…">
|
||||||
|
<!ENTITY zotero.pdfReader.rotatePageLeft "Seite links drehen">
|
||||||
|
<!ENTITY zotero.pdfReader.rotatePageRight "Seite rechts drehen">
|
||||||
|
<!ENTITY zotero.pdfReader.rotatePage180 "Seite 180° drehen">
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue