- Added UI elements for fulltext indexing, including new Search prefpane
- Added pdfinfo support to determine number of PDF pages (requires custom binary) - Automatic downloading and installation of customized Xpdf tools from zotero.org Other changes: - Various API Zotero.Fulltext API changes - Prevent buggy automatic prefpane sizing - New 'refresh' Notifier action to just reselect the currently selected item without sending a 'modify' trigger - Zotero.File.putContents(file, str) -- can only handle ASCII text - Zotero.isLinux property
This commit is contained in:
parent
f5761d507a
commit
d921d8239a
|
@ -50,6 +50,8 @@ var ZoteroPane = new function()
|
||||||
this.updateTagFilter = updateTagFilter;
|
this.updateTagFilter = updateTagFilter;
|
||||||
this.onCollectionSelected = onCollectionSelected;
|
this.onCollectionSelected = onCollectionSelected;
|
||||||
this.itemSelected = itemSelected;
|
this.itemSelected = itemSelected;
|
||||||
|
this.updateItemIndexedState = updateItemIndexedState;
|
||||||
|
this.reindexItem = reindexItem;
|
||||||
this.duplicateSelectedItem = duplicateSelectedItem;
|
this.duplicateSelectedItem = duplicateSelectedItem;
|
||||||
this.deleteSelectedItem = deleteSelectedItem;
|
this.deleteSelectedItem = deleteSelectedItem;
|
||||||
this.deleteSelectedCollection = deleteSelectedCollection;
|
this.deleteSelectedCollection = deleteSelectedCollection;
|
||||||
|
@ -852,6 +854,20 @@ var ZoteroPane = new function()
|
||||||
|
|
||||||
document.getElementById('zotero-attachment-view').setAttribute('label', str);
|
document.getElementById('zotero-attachment-view').setAttribute('label', str);
|
||||||
|
|
||||||
|
// Display page count
|
||||||
|
var pages = Zotero.Fulltext.getPages(item.ref.getID()).total;
|
||||||
|
var pagesRow = document.getElementById('zotero-attachment-pages');
|
||||||
|
if (pages) {
|
||||||
|
var str = Zotero.getString('itemFields.pages') + ': ' + pages;
|
||||||
|
pagesRow.setAttribute('value', str);
|
||||||
|
pagesRow.setAttribute('hidden', false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pagesRow.setAttribute('hidden', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateItemIndexedState();
|
||||||
|
|
||||||
var noteEditor = document.getElementById('zotero-attachment-note-editor');
|
var noteEditor = document.getElementById('zotero-attachment-note-editor');
|
||||||
noteEditor.item = null;
|
noteEditor.item = null;
|
||||||
noteEditor.note = item.ref;
|
noteEditor.note = item.ref;
|
||||||
|
@ -881,6 +897,65 @@ var ZoteroPane = new function()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update Indexed: (Yes|No|Partial) line in attachment info pane
|
||||||
|
*/
|
||||||
|
function updateItemIndexedState() {
|
||||||
|
var indexBox = document.getElementById('zotero-attachment-index-box');
|
||||||
|
var indexStatus = document.getElementById('zotero-attachment-index-status');
|
||||||
|
var reindexButton = document.getElementById('zotero-attachment-reindex');
|
||||||
|
|
||||||
|
var item = this.itemsView._getItemAtRow(this.itemsView.selection.currentIndex);
|
||||||
|
var status = Zotero.Fulltext.getIndexedState(item.ref.getID());
|
||||||
|
var str = 'fulltext.indexState.';
|
||||||
|
switch (status) {
|
||||||
|
case Zotero.Fulltext.INDEX_STATE_UNAVAILABLE:
|
||||||
|
str += 'unavailable';
|
||||||
|
break;
|
||||||
|
case Zotero.Fulltext.INDEX_STATE_UNINDEXED:
|
||||||
|
str = 'general.no';
|
||||||
|
break;
|
||||||
|
case Zotero.Fulltext.INDEX_STATE_PARTIAL:
|
||||||
|
str += 'partial';
|
||||||
|
break;
|
||||||
|
case Zotero.Fulltext.INDEX_STATE_INDEXED:
|
||||||
|
str = 'general.yes';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
str = Zotero.getString('fulltext.indexState.indexed') + ': ' +
|
||||||
|
Zotero.getString(str);
|
||||||
|
indexStatus.setAttribute('value', str);
|
||||||
|
|
||||||
|
// Reindex button tooltip (string stored in zotero.properties)
|
||||||
|
var str = Zotero.getString('pane.items.menu.reindexItem');
|
||||||
|
reindexButton.setAttribute('tooltiptext', str);
|
||||||
|
|
||||||
|
if (Zotero.Fulltext.canReindex(item.ref.getID())) {
|
||||||
|
reindexButton.setAttribute('hidden', false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
reindexButton.setAttribute('hidden', true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function reindexItem() {
|
||||||
|
var items = this.getSelectedItems();
|
||||||
|
if (!items) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i=0; i<items.length; i++) {
|
||||||
|
if (!items[i].isAttachment()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var itemID = items[i].getID();
|
||||||
|
Zotero.Fulltext.indexItems(itemID, true);
|
||||||
|
}
|
||||||
|
this.updateItemIndexedState();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function duplicateSelectedItem() {
|
function duplicateSelectedItem() {
|
||||||
var newItemID = this.getSelectedItems()[0].clone();
|
var newItemID = this.getSelectedItems()[0].clone();
|
||||||
var newItem = Zotero.Items.get(newItemID);
|
var newItem = Zotero.Items.get(newItemID);
|
||||||
|
@ -1280,7 +1355,9 @@ var ZoteroPane = new function()
|
||||||
sep3: 9,
|
sep3: 9,
|
||||||
exportItems: 10,
|
exportItems: 10,
|
||||||
createBib: 11,
|
createBib: 11,
|
||||||
loadReport: 12
|
loadReport: 12,
|
||||||
|
sep4: 13,
|
||||||
|
reindexItem: 14
|
||||||
};
|
};
|
||||||
|
|
||||||
var menu = document.getElementById('zotero-itemmenu');
|
var menu = document.getElementById('zotero-itemmenu');
|
||||||
|
@ -1297,6 +1374,22 @@ var ZoteroPane = new function()
|
||||||
var multiple = '.multiple';
|
var multiple = '.multiple';
|
||||||
hide.push(m.showInLibrary, m.sep1, m.addNote, m.attachSnapshot,
|
hide.push(m.showInLibrary, m.sep1, m.addNote, m.attachSnapshot,
|
||||||
m.attachLink, m.sep2, m.duplicateItem);
|
m.attachLink, m.sep2, m.duplicateItem);
|
||||||
|
|
||||||
|
// If all items can be reindexed, show option
|
||||||
|
var items = this.getSelectedItems();
|
||||||
|
var canIndex = true;
|
||||||
|
for (var i=0; i<items.length; i++) {
|
||||||
|
if (!Zotero.Fulltext.canReindex()) {
|
||||||
|
canIndex = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (canIndex) {
|
||||||
|
show.push(m.sep4, m.reindexItem);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hide.push(m.sep4, m.reindexItem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Single item selected
|
// Single item selected
|
||||||
else
|
else
|
||||||
|
@ -1324,12 +1417,21 @@ var ZoteroPane = new function()
|
||||||
|
|
||||||
if (item.isAttachment()) {
|
if (item.isAttachment()) {
|
||||||
hide.push(m.duplicateItem);
|
hide.push(m.duplicateItem);
|
||||||
|
// If not linked URL, show reindex line
|
||||||
|
if (Zotero.Fulltext.canReindex(item.getID())) {
|
||||||
|
show.push(m.sep4, m.reindexItem);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hide.push(m.sep4, m.reindexItem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
show.push(m.duplicateItem);
|
show.push(m.duplicateItem);
|
||||||
|
hide.push(m.sep4, m.reindexItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// No items selected
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Show in Library
|
// Show in Library
|
||||||
|
@ -1342,7 +1444,7 @@ var ZoteroPane = new function()
|
||||||
|
|
||||||
disable.push(m.showInLibrary, m.duplicateItem, m.deleteItem,
|
disable.push(m.showInLibrary, m.duplicateItem, m.deleteItem,
|
||||||
m.deleteFromLibrary, m.exportItems, m.createBib, m.loadReport);
|
m.deleteFromLibrary, m.exportItems, m.createBib, m.loadReport);
|
||||||
hide.push(m.addNote, m.attachSnapshot, m.attachLink, m.sep2);
|
hide.push(m.addNote, m.attachSnapshot, m.attachLink, m.sep2, m.sep4, m.reindexItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove from collection
|
// Remove from collection
|
||||||
|
@ -1361,6 +1463,7 @@ var ZoteroPane = new function()
|
||||||
menu.childNodes[m.exportItems].setAttribute('label', Zotero.getString('pane.items.menu.export' + multiple));
|
menu.childNodes[m.exportItems].setAttribute('label', Zotero.getString('pane.items.menu.export' + multiple));
|
||||||
menu.childNodes[m.createBib].setAttribute('label', Zotero.getString('pane.items.menu.createBib' + multiple));
|
menu.childNodes[m.createBib].setAttribute('label', Zotero.getString('pane.items.menu.createBib' + multiple));
|
||||||
menu.childNodes[m.loadReport].setAttribute('label', Zotero.getString('pane.items.menu.generateReport' + multiple));
|
menu.childNodes[m.loadReport].setAttribute('label', Zotero.getString('pane.items.menu.generateReport' + multiple));
|
||||||
|
menu.childNodes[m.reindexItem].setAttribute('label', Zotero.getString('pane.items.menu.reindexItem' + multiple));
|
||||||
|
|
||||||
for (var i in disable)
|
for (var i in disable)
|
||||||
{
|
{
|
||||||
|
|
|
@ -101,6 +101,8 @@
|
||||||
<menuitem oncommand="Zotero_File_Interface.exportItems();"/>
|
<menuitem oncommand="Zotero_File_Interface.exportItems();"/>
|
||||||
<menuitem oncommand="Zotero_File_Interface.bibliographyFromItems();"/>
|
<menuitem oncommand="Zotero_File_Interface.bibliographyFromItems();"/>
|
||||||
<menuitem oncommand="Zotero_Report_Interface.loadItemReport()"/>
|
<menuitem oncommand="Zotero_Report_Interface.loadItemReport()"/>
|
||||||
|
<menuseparator/>
|
||||||
|
<menuitem oncommand="ZoteroPane.reindexItem();"/>
|
||||||
</popup>
|
</popup>
|
||||||
</popupset>
|
</popupset>
|
||||||
|
|
||||||
|
@ -305,10 +307,17 @@
|
||||||
<button id="zotero-attachment-view" flex="1" oncommand="ZoteroPane.viewSelectedAttachment(event);"/>
|
<button id="zotero-attachment-view" flex="1" oncommand="ZoteroPane.viewSelectedAttachment(event);"/>
|
||||||
<button id="zotero-attachment-show" label="&zotero.item.attachment.file.show;" flex="1" oncommand="ZoteroPane.showSelectedAttachmentInFilesystem()"/>
|
<button id="zotero-attachment-show" label="&zotero.item.attachment.file.show;" flex="1" oncommand="ZoteroPane.showSelectedAttachmentInFilesystem()"/>
|
||||||
</hbox>
|
</hbox>
|
||||||
<vbox>
|
|
||||||
<label id="zotero-attachment-url" class="text-link" crop="end" onclick="ZoteroPane.loadURI(this.value, event)"/>
|
<label id="zotero-attachment-url" class="text-link" crop="end" onclick="ZoteroPane.loadURI(this.value, event)"/>
|
||||||
|
|
||||||
|
|
||||||
<label id="zotero-attachment-accessed"/>
|
<label id="zotero-attachment-accessed"/>
|
||||||
</vbox>
|
<label id="zotero-attachment-pages"/>
|
||||||
|
|
||||||
|
<hbox id="zotero-attachment-index-box">
|
||||||
|
<label id="zotero-attachment-index-status"/>
|
||||||
|
<toolbarbutton id="zotero-attachment-reindex" oncommand="ZoteroPane.reindexItem()"/>
|
||||||
|
</hbox>
|
||||||
|
|
||||||
<noteeditor id="zotero-attachment-note-editor" notitle="1" flex="1"/>
|
<noteeditor id="zotero-attachment-note-editor" notitle="1" flex="1"/>
|
||||||
</vbox>
|
</vbox>
|
||||||
</deck>
|
</deck>
|
||||||
|
|
|
@ -33,6 +33,7 @@ function init()
|
||||||
|
|
||||||
populateQuickCopyList();
|
populateQuickCopyList();
|
||||||
updateQuickCopyInstructions();
|
updateQuickCopyInstructions();
|
||||||
|
initSearchPane();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -261,9 +262,9 @@ function refreshQuickCopySiteList() {
|
||||||
treeitem.appendChild(treerow);
|
treeitem.appendChild(treerow);
|
||||||
treechildren.appendChild(treeitem);
|
treechildren.appendChild(treeitem);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function deleteSelectedQuickCopySite() {
|
function deleteSelectedQuickCopySite() {
|
||||||
var tree = document.getElementById('quickCopy-siteSettings');
|
var tree = document.getElementById('quickCopy-siteSettings');
|
||||||
var treeitem = tree.lastChild.childNodes[tree.currentIndex];
|
var treeitem = tree.lastChild.childNodes[tree.currentIndex];
|
||||||
|
@ -291,6 +292,467 @@ function updateQuickCopyInstructions() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function rebuildIndexPrompt() {
|
||||||
|
var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
|
||||||
|
createInstance(Components.interfaces.nsIPromptService);
|
||||||
|
var buttonFlags = (ps.BUTTON_POS_0) * (ps.BUTTON_TITLE_IS_STRING)
|
||||||
|
+ (ps.BUTTON_POS_1) * (ps.BUTTON_TITLE_IS_STRING)
|
||||||
|
+ (ps.BUTTON_POS_2) * (ps.BUTTON_TITLE_CANCEL);
|
||||||
|
|
||||||
|
var index = ps.confirmEx(null,
|
||||||
|
Zotero.getString('zotero.preferences.search.rebuildIndex'),
|
||||||
|
Zotero.getString('zotero.preferences.search.rebuildWarning',
|
||||||
|
Zotero.getString('zotero.preferences.search.indexUnindexed')),
|
||||||
|
buttonFlags,
|
||||||
|
Zotero.getString('zotero.preferences.search.rebuildIndex'),
|
||||||
|
Zotero.getString('zotero.preferences.search.indexUnindexed'),
|
||||||
|
null, null, {});
|
||||||
|
|
||||||
|
if (index == 0) {
|
||||||
|
Zotero.Fulltext.rebuildIndex();
|
||||||
|
}
|
||||||
|
else if (index == 1) {
|
||||||
|
Zotero.Fulltext.rebuildIndex(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
updateIndexStats();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function clearIndexPrompt() {
|
||||||
|
var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
|
||||||
|
createInstance(Components.interfaces.nsIPromptService);
|
||||||
|
var buttonFlags = (ps.BUTTON_POS_0) * (ps.BUTTON_TITLE_IS_STRING)
|
||||||
|
+ (ps.BUTTON_POS_1) * (ps.BUTTON_TITLE_IS_STRING)
|
||||||
|
+ (ps.BUTTON_POS_2) * (ps.BUTTON_TITLE_CANCEL);
|
||||||
|
|
||||||
|
var index = ps.confirmEx(null,
|
||||||
|
Zotero.getString('zotero.preferences.search.clearIndex'),
|
||||||
|
Zotero.getString('zotero.preferences.search.clearWarning',
|
||||||
|
Zotero.getString('zotero.preferences.search.clearNonLinkedURLs')),
|
||||||
|
buttonFlags,
|
||||||
|
Zotero.getString('zotero.preferences.search.clearIndex'),
|
||||||
|
Zotero.getString('zotero.preferences.search.clearNonLinkedURLs'),
|
||||||
|
null, null, {});
|
||||||
|
|
||||||
|
if (index == 0) {
|
||||||
|
Zotero.Fulltext.clearIndex();
|
||||||
|
}
|
||||||
|
else if (index == 1) {
|
||||||
|
Zotero.Fulltext.clearIndex(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateIndexStats();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function initSearchPane() {
|
||||||
|
document.getElementById('fulltext-rebuildIndex').setAttribute('label',
|
||||||
|
Zotero.getString('zotero.preferences.search.rebuildIndex'));
|
||||||
|
document.getElementById('fulltext-clearIndex').setAttribute('label',
|
||||||
|
Zotero.getString('zotero.preferences.search.clearIndex'));
|
||||||
|
updatePDFToolsStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update window according to installation status for PDF tools
|
||||||
|
* (e.g. status line, install/update button, etc.)
|
||||||
|
*/
|
||||||
|
function updatePDFToolsStatus() {
|
||||||
|
var converterIsRegistered = Zotero.Fulltext.pdfConverterIsRegistered();
|
||||||
|
var infoIsRegistered = Zotero.Fulltext.pdfInfoIsRegistered();
|
||||||
|
|
||||||
|
var converterStatusLabel = document.getElementById('pdfconverter-status');
|
||||||
|
var infoStatusLabel = document.getElementById('pdfinfo-status');
|
||||||
|
var requiredLabel = document.getElementById('pdftools-required');
|
||||||
|
var updateButton = document.getElementById('pdftools-update-button');
|
||||||
|
var documentationLink = document.getElementById('pdftools-documentation-link');
|
||||||
|
var settingsBox = document.getElementById('pdftools-settings');
|
||||||
|
|
||||||
|
// If we haven't already generated the required and documentation messages
|
||||||
|
if (!converterIsRegistered && !requiredLabel.hasChildNodes()) {
|
||||||
|
var utils = new Zotero.Utilities();
|
||||||
|
|
||||||
|
// Xpdf link
|
||||||
|
var str = Zotero.getString('zotero.preferences.search.pdf.toolsRequired',
|
||||||
|
[Zotero.Fulltext.pdfConverterName, Zotero.Fulltext.pdfInfoName,
|
||||||
|
'<a href="' + Zotero.Fulltext.pdfToolsURL + '">'
|
||||||
|
+ Zotero.Fulltext.pdfToolsName + '</a>']);
|
||||||
|
var parts = utils.parseMarkup(str);
|
||||||
|
for (var i=0; i<parts.length; i++) {
|
||||||
|
var part = parts[i];
|
||||||
|
if (part.type == 'text') {
|
||||||
|
var elem = document.createTextNode(part.text);
|
||||||
|
}
|
||||||
|
else if (part.type == 'link') {
|
||||||
|
var elem = document.createElement('label');
|
||||||
|
elem.setAttribute('value', part.text);
|
||||||
|
elem.setAttribute('class', 'text-link');
|
||||||
|
for (var key in part.attributes) {
|
||||||
|
elem.setAttribute(key, part.attributes[key]);
|
||||||
|
|
||||||
|
if (key == 'href') {
|
||||||
|
elem.setAttribute('tooltiptext', part.attributes[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
requiredLabel.appendChild(elem);
|
||||||
|
}
|
||||||
|
|
||||||
|
requiredLabel.appendChild(document.createTextNode(' '
|
||||||
|
+ Zotero.getString('zotero.preferences.search.pdf.automaticInstall')));
|
||||||
|
|
||||||
|
// Documentation link
|
||||||
|
var link = '<a href="http://www.zotero.org/documentation/pdf_fulltext_indexing">'
|
||||||
|
+ Zotero.getString('zotero.preferences.search.pdf.documentationLink')
|
||||||
|
+ '</a>';
|
||||||
|
var str = Zotero.getString('zotero.preferences.search.pdf.advancedUsers', link);
|
||||||
|
var parts = utils.parseMarkup(str);
|
||||||
|
|
||||||
|
for (var i=0; i<parts.length; i++) {
|
||||||
|
var part = parts[i];
|
||||||
|
if (part.type == 'text') {
|
||||||
|
var elem = document.createTextNode(part.text);
|
||||||
|
}
|
||||||
|
else if (part.type == 'link') {
|
||||||
|
var elem = document.createElement('label');
|
||||||
|
elem.setAttribute('value', part.text);
|
||||||
|
elem.setAttribute('class', 'text-link');
|
||||||
|
for (var key in part.attributes) {
|
||||||
|
elem.setAttribute(key, part.attributes[key]);
|
||||||
|
|
||||||
|
if (key == 'href') {
|
||||||
|
elem.setAttribute('tooltiptext', part.attributes[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
documentationLink.appendChild(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// converter status line
|
||||||
|
var prefix = 'zotero.preferences.search.pdf.tool';
|
||||||
|
if (converterIsRegistered) {
|
||||||
|
var version = Zotero.Fulltext.pdfConverterVersion;
|
||||||
|
str = Zotero.getString(prefix + 'Registered',
|
||||||
|
Zotero.getString('zotero.preferences.search.pdf.toolVersionPlatform',
|
||||||
|
[Zotero.Fulltext.pdfConverterName, version]));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
str = Zotero.getString(prefix + 'NotRegistered',
|
||||||
|
[Zotero.Fulltext.pdfConverterFileName]);
|
||||||
|
}
|
||||||
|
converterStatusLabel.setAttribute('value', str);
|
||||||
|
|
||||||
|
// pdfinfo status line
|
||||||
|
if (infoIsRegistered) {
|
||||||
|
var version = Zotero.Fulltext.pdfInfoVersion;
|
||||||
|
str = Zotero.getString(prefix + 'Registered',
|
||||||
|
Zotero.getString('zotero.preferences.search.pdf.toolVersionPlatform',
|
||||||
|
[Zotero.Fulltext.pdfInfoName, version]));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
str = Zotero.getString(prefix + 'NotRegistered',
|
||||||
|
[Zotero.Fulltext.pdfInfoFileName]);
|
||||||
|
}
|
||||||
|
infoStatusLabel.setAttribute('value', str);
|
||||||
|
|
||||||
|
str = converterIsRegistered ?
|
||||||
|
Zotero.getString('general.checkForUpdate') :
|
||||||
|
Zotero.getString('zotero.preferences.search.pdf.checkForInstaller');
|
||||||
|
updateButton.setAttribute('label', str);
|
||||||
|
|
||||||
|
requiredLabel.setAttribute('hidden', converterIsRegistered);
|
||||||
|
documentationLink.setAttribute('hidden', converterIsRegistered);
|
||||||
|
settingsBox.setAttribute('hidden', !converterIsRegistered);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check available versions of PDF tools from server and prompt for installation
|
||||||
|
* if a newer version is available
|
||||||
|
*/
|
||||||
|
function checkPDFToolsDownloadVersion() {
|
||||||
|
var url = Zotero.Fulltext.pdfToolsDownloadBaseURL
|
||||||
|
+ Zotero.platform.replace(' ', '-') + '.latest';
|
||||||
|
|
||||||
|
// Find latest version for this platform
|
||||||
|
var sent = Zotero.Utilities.HTTP.doGet(url, function (xmlhttp) {
|
||||||
|
try {
|
||||||
|
if (xmlhttp.status == 200) {
|
||||||
|
var converterIsRegistered = Zotero.Fulltext.pdfConverterIsRegistered();
|
||||||
|
var infoIsRegistered = Zotero.Fulltext.pdfInfoIsRegistered();
|
||||||
|
var bothRegistered = converterIsRegistered && infoIsRegistered;
|
||||||
|
|
||||||
|
var converterVersion = xmlhttp.responseText.split(/\s/)[0];
|
||||||
|
var infoVersion = xmlhttp.responseText.split(/\s/)[1];
|
||||||
|
|
||||||
|
var converterVersionAvailable = converterVersion &&
|
||||||
|
(!converterIsRegistered ||
|
||||||
|
Zotero.Fulltext.pdfConverterVersion == 'UNKNOWN' ||
|
||||||
|
converterVersion > Zotero.Fulltext.pdfConverterVersion);
|
||||||
|
var infoVersionAvailable = infoVersion &&
|
||||||
|
(!infoIsRegistered ||
|
||||||
|
Zotero.Fulltext.pdfInfoVersion == 'UNKNOWN' ||
|
||||||
|
infoVersion > Zotero.Fulltext.pdfInfoVersion);
|
||||||
|
var bothAvailable = converterVersionAvailable && infoVersionAvailable;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Zotero.debug(converterIsRegistered);
|
||||||
|
Zotero.debug(infoIsRegistered);
|
||||||
|
Zotero.debug(converterVersion);
|
||||||
|
Zotero.debug(infoVersion);
|
||||||
|
Zotero.debug(Zotero.Fulltext.pdfConverterVersion);
|
||||||
|
Zotero.debug(Zotero.Fulltext.pdfInfoVersion);
|
||||||
|
Zotero.debug(converterVersionAvailable);
|
||||||
|
Zotero.debug(infoVersionAvailable);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Up to date -- disable update button
|
||||||
|
if (!converterVersionAvailable && !infoVersionAvailable) {
|
||||||
|
var button = document.getElementById('pdftools-update-button');
|
||||||
|
button.setAttribute('label', Zotero.getString('zotero.preferences.update.upToDate'));
|
||||||
|
button.setAttribute('disabled', true);
|
||||||
|
}
|
||||||
|
// New version available -- display update prompt
|
||||||
|
else {
|
||||||
|
var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
|
||||||
|
createInstance(Components.interfaces.nsIPromptService);
|
||||||
|
var buttonFlags = (ps.BUTTON_POS_0) * (ps.BUTTON_TITLE_IS_STRING)
|
||||||
|
+ (ps.BUTTON_POS_1) * (ps.BUTTON_TITLE_CANCEL);
|
||||||
|
|
||||||
|
var msg = Zotero.getString('zotero.preferences.search.pdf.available'
|
||||||
|
+ ((converterIsRegistered || infoIsRegistered) ? 'Updates' : 'Downloads'),
|
||||||
|
[Zotero.platform, 'zotero.org']) + '\n\n';
|
||||||
|
|
||||||
|
if (converterVersionAvailable) {
|
||||||
|
tvp = Zotero.getString('zotero.preferences.search.pdf.toolVersionPlatform',
|
||||||
|
[Zotero.Fulltext.pdfConverterName, converterVersion]);
|
||||||
|
msg += '- ' + tvp + '\n';
|
||||||
|
}
|
||||||
|
if (infoVersionAvailable) {
|
||||||
|
tvp = Zotero.getString('zotero.preferences.search.pdf.toolVersionPlatform',
|
||||||
|
[Zotero.Fulltext.pdfInfoName, infoVersion]);
|
||||||
|
msg += '- ' + tvp + '\n';
|
||||||
|
}
|
||||||
|
msg += '\n';
|
||||||
|
msg += Zotero.getString('zotero.preferences.search.pdf.zoteroCanInstallVersion'
|
||||||
|
+ (bothAvailable ? 's' : ''));
|
||||||
|
|
||||||
|
var index = ps.confirmEx(null,
|
||||||
|
converterIsRegistered ?
|
||||||
|
Zotero.getString('general.updateAvailable') : '',
|
||||||
|
msg,
|
||||||
|
buttonFlags,
|
||||||
|
converterIsRegistered ?
|
||||||
|
Zotero.getString('general.upgrade') :
|
||||||
|
Zotero.getString('general.install'),
|
||||||
|
null, null, null, {});
|
||||||
|
|
||||||
|
if (index == 0) {
|
||||||
|
var installVersions = {
|
||||||
|
converter: converterVersionAvailable ?
|
||||||
|
converterVersion : null,
|
||||||
|
info: infoVersionAvailable ?
|
||||||
|
infoVersion : null
|
||||||
|
};
|
||||||
|
installPDFTools(installVersions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Version not found for platform
|
||||||
|
else if (xmlhttp.status == 404) {
|
||||||
|
onPDFToolsDownloadError(404);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
onPDFToolsDownloadError(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Browser is offline
|
||||||
|
if (!sent) {
|
||||||
|
onPDFToolsDownloadError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Begin installation of specified PDF tools from server -- does a HEAD call to
|
||||||
|
* make sure file exists and then calls downloadPDFTool() if so
|
||||||
|
*/
|
||||||
|
function installPDFTools(installVersions) {
|
||||||
|
if (!installVersions) {
|
||||||
|
installVersions = {
|
||||||
|
converter: true,
|
||||||
|
info: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// We install the converter first if it's available
|
||||||
|
var url = Zotero.Fulltext.pdfToolsDownloadBaseURL;
|
||||||
|
if (installVersions.converter) {
|
||||||
|
var tool = 'converter';
|
||||||
|
var version = installVersions.converter;
|
||||||
|
url += Zotero.Fulltext.pdfConverterFileName + '-' + installVersions.converter;
|
||||||
|
}
|
||||||
|
else if (installVersions.info) {
|
||||||
|
var tool = 'info';
|
||||||
|
var version = installVersions.info;
|
||||||
|
url += Zotero.Fulltext.pdfInfoFileName + '-' + installVersions.info;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find latest version for this platform
|
||||||
|
var sent = Zotero.Utilities.HTTP.doHead(url, function (xmlhttp) {
|
||||||
|
try {
|
||||||
|
if (xmlhttp.status == 200) {
|
||||||
|
// If doing both and on converter, chain pdfinfo
|
||||||
|
if (installVersions.converter && installVersions.info) {
|
||||||
|
downloadPDFTool(tool, version, function () {
|
||||||
|
return installPDFTools({ info: installVersions.info });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
downloadPDFTool(tool, version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Version not found for platform
|
||||||
|
else if (xmlhttp.status == 404) {
|
||||||
|
onPDFToolsDownloadError(404);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
onPDFToolsDownloadError(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Browser is offline
|
||||||
|
if (!sent) {
|
||||||
|
onPDFToolsDownloadError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Download and install specified PDF tool
|
||||||
|
*/
|
||||||
|
function downloadPDFTool(tool, version, callback) {
|
||||||
|
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
|
||||||
|
.getService(Components.interfaces.nsIIOService);
|
||||||
|
|
||||||
|
if (tool == 'converter') {
|
||||||
|
var fileName = Zotero.Fulltext.pdfConverterFileName;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var fileName = Zotero.Fulltext.pdfInfoFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var url = Zotero.Fulltext.pdfToolsDownloadBaseURL + fileName + '-' + version;
|
||||||
|
var uri = ioService.newURI(url, null, null);
|
||||||
|
|
||||||
|
var file = Zotero.getZoteroDirectory();
|
||||||
|
file.append(fileName);
|
||||||
|
var fileURL = ioService.newFileURI(file);
|
||||||
|
|
||||||
|
const nsIWBP = Components.interfaces.nsIWebBrowserPersist;
|
||||||
|
var wbp = Components.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
|
||||||
|
.createInstance(nsIWBP);
|
||||||
|
|
||||||
|
var progressListener = new Zotero.WebProgressFinishListener(function () {
|
||||||
|
// Set permissions to 755
|
||||||
|
if (Zotero.isMac) {
|
||||||
|
file.permissions = 33261;
|
||||||
|
}
|
||||||
|
else if (Zotero.isLinux) {
|
||||||
|
file.permissions = 493;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the version number to a file
|
||||||
|
var versionFile = Zotero.getZoteroDirectory();
|
||||||
|
versionFile.append(fileName + '.version');
|
||||||
|
Zotero.File.putContents(versionFile, version + '');
|
||||||
|
|
||||||
|
Zotero.Fulltext.registerPDFTool(tool);
|
||||||
|
|
||||||
|
// Used to install info tool after converter
|
||||||
|
if (callback) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
// If done
|
||||||
|
else {
|
||||||
|
updatePDFToolsStatus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
var tr = Components.classes["@mozilla.org/transfer;1"].
|
||||||
|
createInstance(Components.interfaces.nsITransfer);
|
||||||
|
tr.init(uri, fileURL, "", null, null, null, wbp);
|
||||||
|
*/
|
||||||
|
|
||||||
|
document.getElementById('pdftools-update-button').disabled = true;
|
||||||
|
var str = Zotero.getString('zotero.preferences.search.pdf.downloading');
|
||||||
|
document.getElementById('pdftools-update-button').setAttribute('label', str);
|
||||||
|
|
||||||
|
wbp.progressListener = progressListener;
|
||||||
|
Zotero.debug("Saving " + uri.spec + " to " + fileURL.spec);
|
||||||
|
wbp.saveURI(uri, null, null, null, null, fileURL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function onPDFToolsDownloadError(e) {
|
||||||
|
if (e == 404) {
|
||||||
|
var str = Zotero.getString('zotero.preferences.search.pdf.toolDownloadsNotAvailable',
|
||||||
|
Zotero.Fulltext.pdfToolsName) + ' '
|
||||||
|
+ Zotero.getString('zotero.preferences.search.pdf.viewManualInstructions');
|
||||||
|
}
|
||||||
|
else if (e) {
|
||||||
|
Components.utils.reportError(e);
|
||||||
|
var str = Zotero.getString('zotero.preferences.search.pdf.toolsDownloadError', Zotero.Fulltext.pdfToolsName)
|
||||||
|
+ ' ' + Zotero.getString('zotero.preferences.search.pdf.tryAgainOrViewManualInstructions');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var info = Components.classes["@mozilla.org/xre/app-info;1"]
|
||||||
|
.getService(Components.interfaces.nsIXULAppInfo);
|
||||||
|
var browser = info.name; // Returns "Firefox" for Firefox
|
||||||
|
var str = Zotero.getString('general.browserIsOffline', browser);
|
||||||
|
}
|
||||||
|
alert(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function updateIndexStats() {
|
||||||
|
var stats = Zotero.Fulltext.getIndexStats();
|
||||||
|
document.getElementById('fulltext-stats-indexed').
|
||||||
|
lastChild.setAttribute('value', stats.indexed);
|
||||||
|
document.getElementById('fulltext-stats-partial').
|
||||||
|
lastChild.setAttribute('value', stats.partial);
|
||||||
|
document.getElementById('fulltext-stats-unindexed').
|
||||||
|
lastChild.setAttribute('value', stats.unindexed);
|
||||||
|
document.getElementById('fulltext-stats-words').
|
||||||
|
lastChild.setAttribute('value', stats.words);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unused
|
||||||
|
*/
|
||||||
|
function revealDataDirectory() {
|
||||||
|
var dataDir = Zotero.getZoteroDirectory();
|
||||||
|
dataDir.QueryInterface(Components.interfaces.nsILocalFile);
|
||||||
|
try {
|
||||||
|
dataDir.reveal();
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
// TODO: This won't work on Linux
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function onOpenURLSelected()
|
function onOpenURLSelected()
|
||||||
{
|
{
|
||||||
|
|
|
@ -66,10 +66,10 @@ To add a new preference:
|
||||||
|
|
||||||
<rows>
|
<rows>
|
||||||
<row>
|
<row>
|
||||||
<hbox>
|
<hbox id="position-menu-box-label">
|
||||||
<label value="&zotero.preferences.position;" control="positionMenu"/>
|
<label value="&zotero.preferences.position;" control="positionMenu"/>
|
||||||
</hbox>
|
</hbox>
|
||||||
<hbox>
|
<hbox id="position-menu-box">
|
||||||
<menulist id="positionMenu" preference="pref-zoteroPaneOnTop">
|
<menulist id="positionMenu" preference="pref-zoteroPaneOnTop">
|
||||||
<menupopup>
|
<menupopup>
|
||||||
<menuitem label="&zotero.preferences.position.above;" value="true"/>
|
<menuitem label="&zotero.preferences.position.above;" value="true"/>
|
||||||
|
@ -151,6 +151,104 @@ To add a new preference:
|
||||||
</prefpane>
|
</prefpane>
|
||||||
|
|
||||||
|
|
||||||
|
<prefpane id="zotero-prefpane-search" label="&zotero.preferences.prefpane.search;"
|
||||||
|
onpaneload="updateIndexStats()">
|
||||||
|
<preferences>
|
||||||
|
<preference id="pref-fulltext-textMaxLength" name="extensions.zotero.fulltext.textMaxLength" type="int"/>
|
||||||
|
<preference id="pref-fulltext-pdfmaxpages" name="extensions.zotero.fulltext.pdfMaxPages" type="int"/>
|
||||||
|
</preferences>
|
||||||
|
|
||||||
|
<groupbox>
|
||||||
|
<caption label="&zotero.preferences.search.fulltextCache;"/>
|
||||||
|
|
||||||
|
<hbox>
|
||||||
|
<button id="fulltext-rebuildIndex" flex="1" oncommand="rebuildIndexPrompt()"/>
|
||||||
|
<button id="fulltext-clearIndex" flex="1" oncommand="clearIndexPrompt()"/>
|
||||||
|
</hbox>
|
||||||
|
|
||||||
|
<grid id="fulltext-settings">
|
||||||
|
<columns>
|
||||||
|
<column/>
|
||||||
|
<column flex="1"/>
|
||||||
|
</columns>
|
||||||
|
|
||||||
|
<rows>
|
||||||
|
<row>
|
||||||
|
<hbox>
|
||||||
|
<label value="&zotero.preferences.fulltext.textMaxLength;"/>
|
||||||
|
</hbox>
|
||||||
|
<hbox>
|
||||||
|
<textbox size="10" preference="pref-fulltext-textMaxLength"/>
|
||||||
|
<label value="(&zotero.preferences.default; 500000)"/>
|
||||||
|
</hbox>
|
||||||
|
</row>
|
||||||
|
</rows>
|
||||||
|
</grid>
|
||||||
|
</groupbox>
|
||||||
|
|
||||||
|
<groupbox id="pdftools-box">
|
||||||
|
<caption label="&zotero.preferences.search.pdfIndexing;"/>
|
||||||
|
|
||||||
|
<label id="pdfconverter-status"/>
|
||||||
|
<label id="pdfinfo-status"/>
|
||||||
|
<label id="pdftools-required" hidden="true"/>
|
||||||
|
<hbox>
|
||||||
|
<button id="pdftools-update-button" flex="1" oncommand="checkPDFToolsDownloadVersion()"/>
|
||||||
|
</hbox>
|
||||||
|
<label id="pdftools-documentation-link" hidden="true"/>
|
||||||
|
|
||||||
|
<grid id="pdftools-settings" hidden="true">
|
||||||
|
<columns>
|
||||||
|
<column/>
|
||||||
|
<column flex="1"/>
|
||||||
|
</columns>
|
||||||
|
|
||||||
|
<rows>
|
||||||
|
<row>
|
||||||
|
<hbox>
|
||||||
|
<label value="&zotero.preferences.fulltext.pdfMaxPages;"/>
|
||||||
|
</hbox>
|
||||||
|
<hbox>
|
||||||
|
<textbox size="5" preference="pref-fulltext-pdfmaxpages"/>
|
||||||
|
<label value="(&zotero.preferences.default; 100)"/>
|
||||||
|
</hbox>
|
||||||
|
</row>
|
||||||
|
</rows>
|
||||||
|
</grid>
|
||||||
|
</groupbox>
|
||||||
|
|
||||||
|
<groupbox id="fulltext-stats">
|
||||||
|
<caption label="&zotero.preferences.search.indexStats;"/>
|
||||||
|
|
||||||
|
<grid>
|
||||||
|
<columns>
|
||||||
|
<column/>
|
||||||
|
<column/>
|
||||||
|
</columns>
|
||||||
|
|
||||||
|
<rows>
|
||||||
|
<row id="fulltext-stats-indexed">
|
||||||
|
<label value="Indexed:"/>
|
||||||
|
<label/>
|
||||||
|
</row>
|
||||||
|
<row id="fulltext-stats-partial">
|
||||||
|
<label value="Partial:"/>
|
||||||
|
<label/>
|
||||||
|
</row>
|
||||||
|
<row id="fulltext-stats-unindexed">
|
||||||
|
<label value="Unindexed:"/>
|
||||||
|
<label/>
|
||||||
|
</row>
|
||||||
|
<row id="fulltext-stats-words">
|
||||||
|
<label value="Words:"/>
|
||||||
|
<label/>
|
||||||
|
</row>
|
||||||
|
</rows>
|
||||||
|
</grid>
|
||||||
|
</groupbox>
|
||||||
|
</prefpane>
|
||||||
|
|
||||||
|
|
||||||
<prefpane id="zotero-prefpane-export" label="&zotero.preferences.prefpane.export;">
|
<prefpane id="zotero-prefpane-export" label="&zotero.preferences.prefpane.export;">
|
||||||
<preferences>
|
<preferences>
|
||||||
<preference id="pref-quickCopy-setting" name="extensions.zotero.export.quickCopy.setting" type="string"/>
|
<preference id="pref-quickCopy-setting" name="extensions.zotero.export.quickCopy.setting" type="string"/>
|
||||||
|
|
|
@ -35,6 +35,7 @@ Zotero.Attachments = new function(){
|
||||||
this.importFromDocument = importFromDocument;
|
this.importFromDocument = importFromDocument;
|
||||||
this.getFileBaseNameFromItem = getFileBaseNameFromItem;
|
this.getFileBaseNameFromItem = getFileBaseNameFromItem;
|
||||||
this.createDirectoryForItem = createDirectoryForItem;
|
this.createDirectoryForItem = createDirectoryForItem;
|
||||||
|
this.getStorageDirectory = getStorageDirectory;
|
||||||
this.getPath = getPath;
|
this.getPath = getPath;
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
@ -499,12 +500,14 @@ Zotero.Attachments = new function(){
|
||||||
|
|
||||||
if (mimeType == 'application/pdf') {
|
if (mimeType == 'application/pdf') {
|
||||||
var f = function() {
|
var f = function() {
|
||||||
Zotero.Fulltext.indexPDF(file, itemID);;
|
Zotero.Fulltext.indexPDF(file, itemID);
|
||||||
|
Zotero.Notifier.trigger('refresh', 'item', itemID);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var f = function() {
|
var f = function() {
|
||||||
Zotero.Fulltext.indexDocument(document, itemID);
|
Zotero.Fulltext.indexDocument(document, itemID);
|
||||||
|
Zotero.Notifier.trigger('refresh', 'item', itemID);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -780,8 +783,7 @@ Zotero.Attachments = new function(){
|
||||||
* Create directory for attachment files within storage directory
|
* Create directory for attachment files within storage directory
|
||||||
*/
|
*/
|
||||||
function createDirectoryForItem(itemID) {
|
function createDirectoryForItem(itemID) {
|
||||||
var dir = Zotero.getStorageDirectory();
|
var dir = this.getStorageDirectory(itemID);
|
||||||
dir.append(itemID);
|
|
||||||
if (!dir.exists()) {
|
if (!dir.exists()) {
|
||||||
dir.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0755);
|
dir.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0755);
|
||||||
}
|
}
|
||||||
|
@ -789,9 +791,16 @@ Zotero.Attachments = new function(){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function getStorageDirectory(itemID) {
|
||||||
|
var dir = Zotero.getStorageDirectory();
|
||||||
|
dir.append(itemID);
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Gets a relative path for imported attachments and an absolute path
|
* Gets a relative descriptor for imported attachments and a persistent
|
||||||
* for files outside the storage directory
|
* descriptor for files outside the storage directory
|
||||||
*/
|
*/
|
||||||
function getPath(file, linkMode) {
|
function getPath(file, linkMode) {
|
||||||
if (linkMode == self.LINK_MODE_IMPORTED_URL ||
|
if (linkMode == self.LINK_MODE_IMPORTED_URL ||
|
||||||
|
|
|
@ -25,6 +25,7 @@ Zotero.File = new function(){
|
||||||
this.getClosestDirectory = getClosestDirectory;
|
this.getClosestDirectory = getClosestDirectory;
|
||||||
this.getSample = getSample;
|
this.getSample = getSample;
|
||||||
this.getContents = getContents;
|
this.getContents = getContents;
|
||||||
|
this.putContents = putContents;
|
||||||
this.getCharsetFromFile = getCharsetFromFile;
|
this.getCharsetFromFile = getCharsetFromFile;
|
||||||
this.addCharsetListener = addCharsetListener;
|
this.addCharsetListener = addCharsetListener;
|
||||||
|
|
||||||
|
@ -114,6 +115,23 @@ Zotero.File = new function(){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write string to a file, overwriting existing file if necessary
|
||||||
|
*
|
||||||
|
* Note: Can only handle ASCII text!
|
||||||
|
*/
|
||||||
|
function putContents(file, str) {
|
||||||
|
if (file.exists()) {
|
||||||
|
file.remove(null);
|
||||||
|
}
|
||||||
|
var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
|
||||||
|
.createInstance(Components.interfaces.nsIFileOutputStream);
|
||||||
|
foStream.init(file, 0x02 | 0x08 | 0x20, 0664, 0); // write, create, truncate
|
||||||
|
foStream.write(str, str.length);
|
||||||
|
foStream.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Not implemented, but it'd sure be great if it were
|
* Not implemented, but it'd sure be great if it were
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -25,11 +25,10 @@ Zotero.Fulltext = new function(){
|
||||||
const CACHE_FILE = '.zotero-ft-cache';
|
const CACHE_FILE = '.zotero-ft-cache';
|
||||||
|
|
||||||
this.init = init;
|
this.init = init;
|
||||||
this.registerPDFToText = registerPDFToText;
|
this.registerPDFTool = registerPDFTool;
|
||||||
this.cacheIsOutdated = cacheIsOutdated;
|
this.pdfConverterIsRegistered = pdfConverterIsRegistered;
|
||||||
this.rebuildCache = rebuildCache;
|
this.pdfInfoIsRegistered = pdfInfoIsRegistered;
|
||||||
this.isCachedMIMEType = isCachedMIMEType;
|
this.isCachedMIMEType = isCachedMIMEType;
|
||||||
this.indexWord = indexWord;
|
|
||||||
this.indexWords = indexWords;
|
this.indexWords = indexWords;
|
||||||
this.indexDocument = indexDocument;
|
this.indexDocument = indexDocument;
|
||||||
this.indexString = indexString;
|
this.indexString = indexString;
|
||||||
|
@ -39,16 +38,62 @@ Zotero.Fulltext = new function(){
|
||||||
this.findTextInFile = findTextInFile;
|
this.findTextInFile = findTextInFile;
|
||||||
this.findTextInItems = findTextInItems;
|
this.findTextInItems = findTextInItems;
|
||||||
this.clearItemWords = clearItemWords;
|
this.clearItemWords = clearItemWords;
|
||||||
|
this.getPages = getPages;
|
||||||
|
this.getTotalPagesFromFile = getTotalPagesFromFile;
|
||||||
|
this.getChars = getChars;
|
||||||
|
this.getTotalCharsFromFile = getTotalCharsFromFile;
|
||||||
|
this.setChars = setChars;
|
||||||
|
this.setPages = setPages;
|
||||||
|
this.getIndexedState = getIndexedState;
|
||||||
|
this.getIndexStats = getIndexStats;
|
||||||
|
this.canReindex = canReindex;
|
||||||
|
this.rebuildIndex = rebuildIndex;
|
||||||
|
this.clearIndex = clearIndex;
|
||||||
|
this.clearCacheFile = clearCacheFile;
|
||||||
|
this.clearCacheFiles = clearCacheFiles;
|
||||||
//this.clearItemContent = clearItemContent;
|
//this.clearItemContent = clearItemContent;
|
||||||
this.purgeUnusedWords = purgeUnusedWords;
|
this.purgeUnusedWords = purgeUnusedWords;
|
||||||
this.HTMLToText = HTMLToText;
|
this.HTMLToText = HTMLToText;
|
||||||
this.semanticSplitter = semanticSplitter;
|
this.semanticSplitter = semanticSplitter;
|
||||||
|
|
||||||
var _pdftotext = null;
|
this.__defineGetter__("pdfToolsDownloadBaseURL", function() { return 'http://www.zotero.org/download/xpdf/'; });
|
||||||
|
this.__defineGetter__("pdfToolsName", function() { return 'Xpdf'; });
|
||||||
|
this.__defineGetter__("pdfToolsURL", function() { return 'http://www.foolabs.com/xpdf/'; });
|
||||||
|
this.__defineGetter__("pdfConverterName", function() { return 'pdftotext'; });
|
||||||
|
this.__defineGetter__("pdfInfoName", function() { return 'pdfinfo'; });
|
||||||
|
this.__defineGetter__("pdfConverterCacheFile", function () { return '.zotero-ft-cache'; });
|
||||||
|
this.__defineGetter__("pdfInfoCacheFile", function () { return '.zotero-ft-info'; });
|
||||||
|
|
||||||
|
this.__defineGetter__("INDEX_STATE_UNAVAILABLE", function () { return 0; });
|
||||||
|
this.__defineGetter__("INDEX_STATE_UNINDEXED", function () { return 1; });
|
||||||
|
this.__defineGetter__("INDEX_STATE_PARTIAL", function () { return 2; });
|
||||||
|
this.__defineGetter__("INDEX_STATE_INDEXED", function () { return 3; });
|
||||||
|
|
||||||
|
|
||||||
|
var _pdfConverterVersion = null;
|
||||||
|
var _pdfConverterFileName = null;
|
||||||
|
var _pdfConverter = null; // nsIFile to executable
|
||||||
|
var _pdfInfoVersion = null;
|
||||||
|
var _pdfInfoFileName = null;
|
||||||
|
var _pdfInfo = null; // nsIFile to executable
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
this.registerPDFToText();
|
var platform = Zotero.platform.replace(' ', '-');
|
||||||
|
_pdfConverterFileName = this.pdfConverterName + '-' + platform;
|
||||||
|
_pdfInfoFileName = this.pdfInfoName + '-' + platform;
|
||||||
|
if (Zotero.isWin) {
|
||||||
|
_pdfConverterFileName += '.exe';
|
||||||
|
}
|
||||||
|
|
||||||
|
this.__defineGetter__("pdfConverterFileName", function() { return _pdfConverterFileName; });
|
||||||
|
this.__defineGetter__("pdfConverterVersion", function() { return _pdfConverterVersion; });
|
||||||
|
this.__defineGetter__("pdfInfoFileName", function() { return _pdfInfoFileName; });
|
||||||
|
this.__defineGetter__("pdfInfoVersion", function() { return _pdfInfoVersion; });
|
||||||
|
|
||||||
|
this.registerPDFTool('converter');
|
||||||
|
this.registerPDFTool('info');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,67 +103,89 @@ Zotero.Fulltext = new function(){
|
||||||
* {platform} is navigator.platform, with spaces replaced by hyphens
|
* {platform} is navigator.platform, with spaces replaced by hyphens
|
||||||
* e.g. "Win32", "Linux-i686", "MacPPC", "MacIntel", etc.
|
* e.g. "Win32", "Linux-i686", "MacPPC", "MacIntel", etc.
|
||||||
*/
|
*/
|
||||||
function registerPDFToText() {
|
function registerPDFTool(tool) {
|
||||||
|
var errMsg = false;
|
||||||
var exec = Zotero.getZoteroDirectory();
|
var exec = Zotero.getZoteroDirectory();
|
||||||
|
|
||||||
var fileName = 'pdftotext-' + Zotero.platform.replace(' ', '-');
|
switch (tool) {
|
||||||
if (Zotero.isWin) {
|
case 'converter':
|
||||||
fileName += '.exe';
|
var toolName = this.pdfConverterName;
|
||||||
}
|
var fileName = _pdfConverterFileName
|
||||||
|
break;
|
||||||
|
|
||||||
var errMsg = false;
|
case 'info':
|
||||||
|
var toolName = this.pdfInfoName;
|
||||||
|
var fileName = _pdfInfoFileName
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw ("Invalid PDF tool type '" + tool + "' in Zotero.Fulltext.registerPDFTool()");
|
||||||
|
}
|
||||||
|
|
||||||
exec.append(fileName);
|
exec.append(fileName);
|
||||||
if (exec.exists()) {
|
if (exec.exists()) {
|
||||||
|
// DEBUG: I'm not sure isSymlink() actually works on any platforms
|
||||||
if (exec.isSymlink()) {
|
if (exec.isSymlink()) {
|
||||||
exec = exec.target;
|
exec = exec.target;
|
||||||
if (!exec.target) {
|
if (!exec.target) {
|
||||||
errMsg = fileName + ' symlink target not found';
|
errMsg = fileName + ' symlink target not found';
|
||||||
|
exec = null;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
_pdftotext = exec;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_pdftotext = exec;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
exec = null;
|
||||||
errMsg = fileName + ' not found';
|
errMsg = fileName + ' not found';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_pdftotext) {
|
if (!exec) {
|
||||||
Zotero.debug('pdftotext registered at ' + _pdftotext.path);
|
if (tool == 'converter') {
|
||||||
}
|
|
||||||
else {
|
|
||||||
_pdftotext = null;
|
|
||||||
Zotero.debug(errMsg + ' -- PDF indexing disabled');
|
Zotero.debug(errMsg + ' -- PDF indexing disabled');
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
versionFile = exec.parent;
|
||||||
|
versionFile.append(fileName + '.version');
|
||||||
|
if (versionFile.exists()) {
|
||||||
|
var version = Zotero.File.getSample(versionFile).split(/[\r\n\s]/)[0];
|
||||||
|
}
|
||||||
|
if (!version) {
|
||||||
|
var version = 'UNKNOWN';
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (tool) {
|
||||||
|
case 'converter':
|
||||||
|
_pdfConverter = exec;
|
||||||
|
_pdfConverterVersion = version;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'info':
|
||||||
|
_pdfInfo = exec;
|
||||||
|
_pdfInfoVersion = version;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Zotero.debug(toolName + ' version ' + version + ' registered at ' + exec.path);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function cacheIsOutdated(){
|
function pdfConverterIsRegistered() {
|
||||||
var sql = "SELECT version FROM version WHERE schema='fulltext'";
|
return !!_pdfConverter;
|
||||||
return Zotero.DB.valueQuery(sql) < FULLTEXT_VERSION;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function rebuildCache(){
|
function pdfInfoIsRegistered() {
|
||||||
Zotero.DB.beginTransaction();
|
return !!_pdfInfo;
|
||||||
Zotero.DB.query("DELETE FROM fulltextWords");
|
|
||||||
Zotero.DB.query("DELETE FROM fulltextItems");
|
|
||||||
//Zotero.DB.query("DELETE FROM fulltextContent");
|
|
||||||
|
|
||||||
var sql = "SELECT itemID FROM itemAttachments";
|
|
||||||
var items = Zotero.DB.columnQuery(sql);
|
|
||||||
if (items) {
|
|
||||||
this.indexItems(items);
|
|
||||||
}
|
|
||||||
|
|
||||||
Zotero.DB.commitTransaction();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns true if MIME type is converted to text and cached before indexing
|
||||||
|
* (e.g. application/pdf is run through pdftotext)
|
||||||
|
*/
|
||||||
function isCachedMIMEType(mimeType) {
|
function isCachedMIMEType(mimeType) {
|
||||||
switch (mimeType) {
|
switch (mimeType) {
|
||||||
case 'application/pdf':
|
case 'application/pdf':
|
||||||
|
@ -128,29 +195,6 @@ Zotero.Fulltext = new function(){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Index a single word
|
|
||||||
*
|
|
||||||
* Note: not used
|
|
||||||
*/
|
|
||||||
function indexWord(itemID, word){
|
|
||||||
Zotero.DB.beginTransaction();
|
|
||||||
|
|
||||||
var sql = "SELECT wordID FROM fulltextWords WHERE word=?";
|
|
||||||
var wordID = Zotero.DB.valueQuery(sql, {string:word});
|
|
||||||
|
|
||||||
if (!wordID){
|
|
||||||
var sql = "INSERT INTO fulltextWords (word) VALUES (?)";
|
|
||||||
var wordID = Zotero.DB.query(sql, {string:word});
|
|
||||||
}
|
|
||||||
|
|
||||||
var sql = "INSERT OR IGNORE INTO fulltextItems VALUES (?,?)";
|
|
||||||
Zotero.DB.query(sql, [wordID, itemID]);
|
|
||||||
|
|
||||||
Zotero.DB.commitTransaction();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Index multiple words at once
|
* Index multiple words at once
|
||||||
*/
|
*/
|
||||||
|
@ -179,9 +223,12 @@ Zotero.Fulltext = new function(){
|
||||||
existing['_' + wordIDs[i]['word']] = wordIDs[i]['wordID'];
|
existing['_' + wordIDs[i]['word']] = wordIDs[i]['wordID'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Zotero.DB.query("REPLACE INTO fulltextItems (itemID, version) VALUES (?,?)",
|
||||||
|
[itemID, FULLTEXT_VERSION]);
|
||||||
|
|
||||||
// Handle bound parameters manually for optimal speed
|
// Handle bound parameters manually for optimal speed
|
||||||
var statement1 = Zotero.DB.getStatement("INSERT INTO fulltextWords (word) VALUES (?)");
|
var statement1 = Zotero.DB.getStatement("INSERT INTO fulltextWords (word) VALUES (?)");
|
||||||
var statement2 = Zotero.DB.getStatement("INSERT OR IGNORE INTO fulltextItems VALUES (?,?)");
|
var statement2 = Zotero.DB.getStatement("INSERT OR IGNORE INTO fulltextItemWords VALUES (?,?)");
|
||||||
|
|
||||||
for each(var word in words){
|
for each(var word in words){
|
||||||
if (existing['_' + word]){
|
if (existing['_' + word]){
|
||||||
|
@ -206,6 +253,9 @@ Zotero.Fulltext = new function(){
|
||||||
|
|
||||||
|
|
||||||
function indexString(text, charset, itemID){
|
function indexString(text, charset, itemID){
|
||||||
|
try {
|
||||||
|
Zotero.UnresponsiveScriptIndicator.disable();
|
||||||
|
|
||||||
var words = semanticSplitter(text, charset);
|
var words = semanticSplitter(text, charset);
|
||||||
|
|
||||||
Zotero.DB.beginTransaction();
|
Zotero.DB.beginTransaction();
|
||||||
|
@ -220,6 +270,10 @@ Zotero.Fulltext = new function(){
|
||||||
|
|
||||||
Zotero.DB.commitTransaction();
|
Zotero.DB.commitTransaction();
|
||||||
}
|
}
|
||||||
|
finally {
|
||||||
|
Zotero.UnresponsiveScriptIndicator.enable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function indexDocument(document, itemID){
|
function indexDocument(document, itemID){
|
||||||
|
@ -241,20 +295,23 @@ Zotero.Fulltext = new function(){
|
||||||
|
|
||||||
var text = document.body.innerHTML;
|
var text = document.body.innerHTML;
|
||||||
|
|
||||||
var max = Zotero.Prefs.get('fulltext.textMaxLength');
|
var maxLength = Zotero.Prefs.get('fulltext.textMaxLength');
|
||||||
if (text.length > max) {
|
if (text.length > maxLength) {
|
||||||
Zotero.debug('Only indexing first ' + max + ' characters of item '
|
Zotero.debug('Only indexing first ' + maxLength + ' characters of item '
|
||||||
+ itemID + ' in indexDocument()');
|
+ itemID + ' in indexDocument()');
|
||||||
text = text.substr(0, max);
|
text = text.substr(0, maxLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
text = text.replace(/(>)/g, '$1 ');
|
text = text.replace(/(>)/g, '$1 ');
|
||||||
text = this.HTMLToText(text);
|
text = this.HTMLToText(text);
|
||||||
this.indexString(text, document.characterSet, itemID);
|
this.indexString(text, document.characterSet, itemID);
|
||||||
|
|
||||||
|
var charsIndexed = Math.min(maxLength, text.length);
|
||||||
|
this.setChars(itemID, { indexed: charsIndexed, total: text.length });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function indexFile(file, mimeType, charset, itemID){
|
function indexFile(file, mimeType, charset, itemID, maxLength, isCacheFile) {
|
||||||
if (!file.exists()){
|
if (!file.exists()){
|
||||||
Zotero.debug('File not found in indexFile()', 2);
|
Zotero.debug('File not found in indexFile()', 2);
|
||||||
return false;
|
return false;
|
||||||
|
@ -267,8 +324,22 @@ Zotero.Fulltext = new function(){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (maxLength == undefined || maxLength === true) {
|
||||||
|
maxLength = Zotero.Prefs.get('fulltext.textMaxLength');
|
||||||
|
}
|
||||||
|
// If maxLength is explicitly false, index everything
|
||||||
|
else if (maxLength === false || maxLength === null) {
|
||||||
|
maxLength = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (mimeType == 'application/pdf') {
|
if (mimeType == 'application/pdf') {
|
||||||
return this.indexPDF(file, itemID);
|
try {
|
||||||
|
Zotero.UnresponsiveScriptIndicator.disable();
|
||||||
|
return this.indexPDF(file, itemID, !maxLength);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
Zotero.UnresponsiveScriptIndicator.enable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mimeType.substr(0, 5)!='text/'){
|
if (mimeType.substr(0, 5)!='text/'){
|
||||||
|
@ -283,23 +354,36 @@ Zotero.Fulltext = new function(){
|
||||||
|
|
||||||
Zotero.debug('Indexing file ' + file.path);
|
Zotero.debug('Indexing file ' + file.path);
|
||||||
|
|
||||||
var maxLength = Zotero.Prefs.get('fulltext.textMaxLength');
|
|
||||||
var text = Zotero.File.getContents(file, charset, maxLength);
|
var text = Zotero.File.getContents(file, charset, maxLength);
|
||||||
// Split elements to avoid word concatentation
|
// Split elements to avoid word concatentation
|
||||||
text = text.replace(/(>)/g, '$1 ');
|
text = text.replace(/(>)/g, '$1 ');
|
||||||
text = this.HTMLToText(text);
|
text = this.HTMLToText(text);
|
||||||
this.indexString(text, charset, itemID);
|
this.indexString(text, charset, itemID);
|
||||||
|
|
||||||
|
// Record number of characters indexed
|
||||||
|
if (!isCacheFile) {
|
||||||
|
var totalChars = this.getTotalCharsFromFile(itemID);
|
||||||
|
if (maxLength) {
|
||||||
|
var charsIndexed = Math.min(maxLength, totalChars);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var charsIndexed = totalChars;
|
||||||
|
}
|
||||||
|
this.setChars(itemID, { indexed: charsIndexed, total: totalChars });
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Run PDF through pdftotext to generate .zotero-ft-cache and pass the
|
* Run PDF through pdfinfo and pdftotext to generate .zotero-ft-info
|
||||||
* text file back to indexFile()
|
* and .zotero-ft-cache, and pass the text file back to indexFile()
|
||||||
|
*
|
||||||
|
* @param allPages If true, index all pages rather than pdfMaxPages
|
||||||
*/
|
*/
|
||||||
function indexPDF(file, itemID) {
|
function indexPDF(file, itemID, allPages) {
|
||||||
if (!_pdftotext) {
|
if (!_pdfConverter) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,25 +397,63 @@ Zotero.Fulltext = new function(){
|
||||||
else {
|
else {
|
||||||
var cacheFile = file.parent;
|
var cacheFile = file.parent;
|
||||||
}
|
}
|
||||||
cacheFile.append(CACHE_FILE);
|
cacheFile.append(this.pdfConverterCacheFile);
|
||||||
|
|
||||||
|
if (_pdfInfo) {
|
||||||
|
var infoFile = cacheFile.parent;
|
||||||
|
infoFile.append(this.pdfInfoCacheFile);
|
||||||
|
Zotero.debug('Running pdfinfo ' + file.path + '" "' + infoFile.path + '"');
|
||||||
|
|
||||||
var proc = Components.classes["@mozilla.org/process/util;1"].
|
var proc = Components.classes["@mozilla.org/process/util;1"].
|
||||||
createInstance(Components.interfaces.nsIProcess);
|
createInstance(Components.interfaces.nsIProcess);
|
||||||
proc.init(_pdftotext);
|
proc.init(_pdfInfo);
|
||||||
var maxPages = Zotero.Prefs.get('fulltext.pdfMaxPages');
|
|
||||||
Zotero.debug('Running pdftotext -nopgbrk -l ' + maxPages +
|
var args = [file.path, infoFile.path];
|
||||||
' "' + file.path + '" "' + cacheFile.path + '"');
|
|
||||||
var args = ['-nopgbrk', '-l', maxPages, file.path, cacheFile.path];
|
|
||||||
proc.run(true, args, args.length);
|
proc.run(true, args, args.length);
|
||||||
|
|
||||||
if (cacheFile.exists()) {
|
var totalPages = this.getTotalPagesFromFile(itemID);
|
||||||
return this.indexFile(cacheFile, 'text/plain', 'utf-8', itemID);
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
Zotero.debug(this.pdfInfoName + " is not available");
|
||||||
|
}
|
||||||
|
|
||||||
|
var maxPages = Zotero.Prefs.get('fulltext.pdfMaxPages');
|
||||||
|
|
||||||
|
Zotero.debug('Running pdftotext -nopgbrk '
|
||||||
|
+ (allPages ? '' : '-l ' + maxPages) + ' "' + file.path + '" "'
|
||||||
|
+ cacheFile.path + '"');
|
||||||
|
|
||||||
|
var proc = Components.classes["@mozilla.org/process/util;1"].
|
||||||
|
createInstance(Components.interfaces.nsIProcess);
|
||||||
|
proc.init(_pdfConverter);
|
||||||
|
|
||||||
|
var args = ['-nopgbrk'];
|
||||||
|
if (allPages) {
|
||||||
|
if (totalPages) {
|
||||||
|
var pagesIndexed = totalPages;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
args.push('-l', maxPages);
|
||||||
|
var pagesIndexed = Math.min(maxPages, totalPages);
|
||||||
|
}
|
||||||
|
args.push(file.path, cacheFile.path);
|
||||||
|
proc.run(true, args, args.length);
|
||||||
|
|
||||||
|
if (!cacheFile.exists()) {
|
||||||
|
Zotero.debug("Cache file doesn't exist!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Zotero.DB.beginTransaction();
|
||||||
|
this.indexFile(cacheFile, 'text/plain', 'utf-8', itemID, false, true);
|
||||||
|
this.setPages(itemID, { indexed: pagesIndexed, total: totalPages });
|
||||||
|
Zotero.DB.commitTransaction();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
function indexItems(items){
|
|
||||||
|
function indexItems(items, complete) {
|
||||||
if (items.constructor.name != 'Array') {
|
if (items.constructor.name != 'Array') {
|
||||||
items = [items];
|
items = [items];
|
||||||
}
|
}
|
||||||
|
@ -352,12 +474,9 @@ Zotero.Fulltext = new function(){
|
||||||
}
|
}
|
||||||
|
|
||||||
this.indexFile(file, i.getAttachmentMimeType(),
|
this.indexFile(file, i.getAttachmentMimeType(),
|
||||||
i.getAttachmentCharset(), i.getID());
|
i.getAttachmentCharset(), i.getID(), !complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
var sql = "REPLACE INTO version (schema,version) VALUES (?,?)";
|
|
||||||
Zotero.DB.query(sql, ['fulltext', FULLTEXT_VERSION]);
|
|
||||||
|
|
||||||
Zotero.DB.commitTransaction();
|
Zotero.DB.commitTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -497,10 +616,273 @@ Zotero.Fulltext = new function(){
|
||||||
|
|
||||||
|
|
||||||
function clearItemWords(itemID){
|
function clearItemWords(itemID){
|
||||||
|
Zotero.DB.beginTransaction();
|
||||||
Zotero.DB.query("DELETE FROM fulltextItems WHERE itemID=" + itemID);
|
Zotero.DB.query("DELETE FROM fulltextItems WHERE itemID=" + itemID);
|
||||||
|
Zotero.DB.query("DELETE FROM fulltextItemWords WHERE itemID=" + itemID);
|
||||||
|
Zotero.DB.commitTransaction();
|
||||||
|
|
||||||
// Delete fulltext cache file if there is one
|
// Delete fulltext cache file if there is one
|
||||||
|
this.clearCacheFile(itemID);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function getPages(itemID, force) {
|
||||||
|
var sql = "SELECT indexedPages AS indexed, totalPages AS total "
|
||||||
|
+ "FROM fulltextItems WHERE itemID=?";
|
||||||
|
var result = Zotero.DB.rowQuery(sql, itemID);
|
||||||
|
return result ? result : { indexed: null, total: null };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Gets the number of pages from the PDF info cache file
|
||||||
|
*/
|
||||||
|
function getTotalPagesFromFile(itemID) {
|
||||||
var item = Zotero.Items.get(itemID);
|
var item = Zotero.Items.get(itemID);
|
||||||
|
var file = Zotero.Attachments.getStorageDirectory(item.getID());
|
||||||
|
file.append(this.pdfInfoCacheFile);
|
||||||
|
if (!file.exists()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var contents = Zotero.File.getContents(file);
|
||||||
|
try {
|
||||||
|
// Parse pdfinfo output
|
||||||
|
var pages = contents.match('Pages:[^0-9]+([0-9]+)')[1];
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
Zotero.debug(e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return pages;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function getChars(itemID) {
|
||||||
|
var sql = "SELECT indexedChars AS indexed, totalChars AS total "
|
||||||
|
+ "FROM fulltextItems WHERE itemID=?";
|
||||||
|
var result = Zotero.DB.rowQuery(sql, itemID);
|
||||||
|
return result ? result : { indexed: null, total: null };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Gets the number of characters from the PDF converter cache file
|
||||||
|
*/
|
||||||
|
function getTotalCharsFromFile(itemID) {
|
||||||
|
var item = Zotero.Items.get(itemID);
|
||||||
|
switch (item.getAttachmentMimeType()) {
|
||||||
|
case 'application/pdf':
|
||||||
|
var file = Zotero.Attachments.getStorageDirectory(itemID);
|
||||||
|
file.append(this.pdfConverterCacheFile);
|
||||||
|
if (!file.exists()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
var file = item.getFile();
|
||||||
|
if (!file) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Zotero.File.getContents(file).length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function setPages(itemID, obj) {
|
||||||
|
var sql = "UPDATE fulltextItems SET indexedPages=?, totalPages=? WHERE itemID=?";
|
||||||
|
Zotero.DB.query(sql, [obj.indexed ? obj.indexed : null,
|
||||||
|
obj.total ? obj.total : null, itemID]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function setChars(itemID, obj) {
|
||||||
|
var sql = "UPDATE fulltextItems SET indexedChars=?, totalChars=? WHERE itemID=?";
|
||||||
|
Zotero.DB.query(sql, [obj.indexed ? obj.indexed : null,
|
||||||
|
obj.total ? obj.total : null, itemID]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Gets the indexed state of an item,
|
||||||
|
*/
|
||||||
|
function getIndexedState(itemID) {
|
||||||
|
var item = Zotero.Items.get(itemID);
|
||||||
|
if (!item) {
|
||||||
|
throw ("Invalid item " + itemID + " in Zotero.Fulltext.getIndexedState()");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!item.isAttachment()) {
|
||||||
|
throw ('Item ' + itemID + ' is not an attachment in Zotero.Fulltext.getIndexedState()');
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (item.getAttachmentMimeType()) {
|
||||||
|
// Use pages for PDFs
|
||||||
|
case 'application/pdf':
|
||||||
|
var pages = this.getPages(itemID);
|
||||||
|
var indexedPages = pages.indexed;
|
||||||
|
var totalPages = pages.total;
|
||||||
|
if (!totalPages) {
|
||||||
|
if (!indexedPages) {
|
||||||
|
var status = this.INDEX_STATE_UNINDEXED;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var status = this.INDEX_STATE_UNAVAILABLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!indexedPages) {
|
||||||
|
var status = this.INDEX_STATE_UNINDEXED;
|
||||||
|
}
|
||||||
|
else if (indexedPages < totalPages) {
|
||||||
|
var status = this.INDEX_STATE_PARTIAL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var status = this.INDEX_STATE_INDEXED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Use chars
|
||||||
|
default:
|
||||||
|
var chars = this.getChars(itemID);
|
||||||
|
var indexedChars = chars.indexed;
|
||||||
|
var totalChars = chars.total;
|
||||||
|
if (!totalChars) {
|
||||||
|
if (!indexedChars) {
|
||||||
|
var status = this.INDEX_STATE_UNINDEXED;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var status = this.INDEX_STATE_UNAVAILABLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!indexedChars) {
|
||||||
|
var status = this.INDEX_STATE_UNINDEXED;
|
||||||
|
}
|
||||||
|
else if (indexedChars < totalChars) {
|
||||||
|
var status = this.INDEX_STATE_PARTIAL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var status = this.INDEX_STATE_INDEXED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function getIndexStats() {
|
||||||
|
var sql = "SELECT COUNT(*) FROM fulltextItems WHERE "
|
||||||
|
+ "(indexedPages IS NOT NULL AND indexedPages=totalPages) OR "
|
||||||
|
+ "(indexedChars IS NOT NULL AND indexedChars=totalChars)"
|
||||||
|
var indexed = Zotero.DB.valueQuery(sql);
|
||||||
|
|
||||||
|
var sql = "SELECT COUNT(*) FROM fulltextItems WHERE "
|
||||||
|
+ "(indexedPages IS NOT NULL AND indexedPages<totalPages) OR "
|
||||||
|
+ "(indexedChars IS NOT NULL AND indexedChars<totalChars)"
|
||||||
|
var partial = Zotero.DB.valueQuery(sql);
|
||||||
|
|
||||||
|
var sql = "SELECT COUNT(*) FROM itemAttachments WHERE itemID NOT IN "
|
||||||
|
+ "(SELECT itemID FROM fulltextItems WHERE "
|
||||||
|
+ "indexedPages IS NOT NULL OR indexedChars IS NOT NULL)";
|
||||||
|
var unindexed = Zotero.DB.valueQuery(sql);
|
||||||
|
|
||||||
|
var sql = "SELECT COUNT(*) FROM fulltextWords";
|
||||||
|
var words = Zotero.DB.valueQuery(sql);
|
||||||
|
|
||||||
|
return { indexed: indexed, partial: partial, unindexed: unindexed,
|
||||||
|
words: words };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns true if an item can be reindexed
|
||||||
|
*
|
||||||
|
* Item must be a non-web-link attachment that isn't already fully indexed
|
||||||
|
*/
|
||||||
|
function canReindex(itemID) {
|
||||||
|
var item = Zotero.Items.get(itemID);
|
||||||
|
if (item && item.isAttachment() && item.getAttachmentLinkMode() !=
|
||||||
|
Zotero.Attachments.LINK_MODE_LINKED_URL) {
|
||||||
|
switch (this.getIndexedState(itemID)) {
|
||||||
|
case this.INDEX_STATE_UNAVAILABLE:
|
||||||
|
case this.INDEX_STATE_UNINDEXED:
|
||||||
|
case this.INDEX_STATE_PARTIAL:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function rebuildIndex(unindexedOnly){
|
||||||
|
Zotero.DB.beginTransaction();
|
||||||
|
|
||||||
|
// Get all attachments other than web links
|
||||||
|
var sql = "SELECT itemID FROM itemAttachments WHERE linkMode!="
|
||||||
|
+ Zotero.Attachments.LINK_MODE_LINKED_URL;
|
||||||
|
if (unindexedOnly) {
|
||||||
|
sql += " AND itemID NOT IN (SELECT itemID FROM fulltextItems "
|
||||||
|
+ "WHERE indexedChars IS NOT NULL OR indexedPages IS NOT NULL)";
|
||||||
|
}
|
||||||
|
var items = Zotero.DB.columnQuery(sql);
|
||||||
|
if (items) {
|
||||||
|
Zotero.DB.query("DELETE FROM fulltextItemWords WHERE itemID IN (" + sql + ")");
|
||||||
|
Zotero.DB.query("DELETE FROM fulltextItems WHERE itemID IN (" + sql + ")");
|
||||||
|
this.indexItems(items);
|
||||||
|
}
|
||||||
|
Zotero.DB.commitTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clears full-text word index and all full-text cache files
|
||||||
|
*/
|
||||||
|
function clearIndex(skipLinkedURLs) {
|
||||||
|
Zotero.DB.beginTransaction();
|
||||||
|
|
||||||
|
var sql = "DELETE FROM fulltextItems";
|
||||||
|
if (skipLinkedURLs) {
|
||||||
|
var linkSQL = "SELECT itemID FROM itemAttachments WHERE linkMode ="
|
||||||
|
+ Zotero.Attachments.LINK_MODE_LINKED_URL;
|
||||||
|
|
||||||
|
sql += " WHERE itemID NOT IN (" + linkSQL + ")";
|
||||||
|
}
|
||||||
|
Zotero.DB.query(sql);
|
||||||
|
|
||||||
|
sql = "DELETE FROM fulltextItemWords";
|
||||||
|
if (skipLinkedURLs) {
|
||||||
|
sql += " WHERE itemID NOT IN (" + linkSQL + ")";
|
||||||
|
}
|
||||||
|
Zotero.DB.query(sql);
|
||||||
|
|
||||||
|
if (skipLinkedURLs) {
|
||||||
|
this.purgeUnusedWords();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Zotero.DB.query("DELETE FROM fulltextWords");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.clearCacheFiles();
|
||||||
|
|
||||||
|
Zotero.DB.commitTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clears cache file for an item
|
||||||
|
*/
|
||||||
|
function clearCacheFile(itemID) {
|
||||||
|
var item = Zotero.Items.get(itemID);
|
||||||
|
if (!item) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!item.isAttachment()) {
|
||||||
|
Zotero.debug("Item " + itemID + " is not an attachment in Zotero.Fulltext.clearCacheFile()");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Zotero.debug('Clearing full-text cache file for item ' + itemID);
|
||||||
switch (item.getAttachmentMimeType()) {
|
switch (item.getAttachmentMimeType()) {
|
||||||
case 'application/pdf':
|
case 'application/pdf':
|
||||||
var cacheFile = _getItemCacheFile();
|
var cacheFile = _getItemCacheFile();
|
||||||
|
@ -509,6 +891,22 @@ Zotero.Fulltext = new function(){
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clear cache files for all attachments
|
||||||
|
*/
|
||||||
|
function clearCacheFiles(skipLinkedURLs) {
|
||||||
|
var sql = "SELECT itemID FROM itemAttachments";
|
||||||
|
if (skipLinkedURLs) {
|
||||||
|
sql += " WHERE linkMode != " + Zotero.Attachments.LINK_MODE_LINKED_URL;
|
||||||
|
}
|
||||||
|
var items = Zotero.DB.columnQuery(sql);
|
||||||
|
for (var i=0; i<items.length; i++) {
|
||||||
|
this.clearCacheFile(items[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -521,7 +919,7 @@ Zotero.Fulltext = new function(){
|
||||||
|
|
||||||
function purgeUnusedWords(){
|
function purgeUnusedWords(){
|
||||||
var sql = "DELETE FROM fulltextWords WHERE wordID NOT IN "
|
var sql = "DELETE FROM fulltextWords WHERE wordID NOT IN "
|
||||||
+ "(SELECT wordID FROM fulltextItems)";
|
+ "(SELECT wordID FROM fulltextItemWords)";
|
||||||
Zotero.DB.query(sql);
|
Zotero.DB.query(sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -626,7 +1024,7 @@ Zotero.Fulltext = new function(){
|
||||||
function _getItemCacheFile(itemID) {
|
function _getItemCacheFile(itemID) {
|
||||||
var cacheFile = Zotero.getStorageDirectory();
|
var cacheFile = Zotero.getStorageDirectory();
|
||||||
cacheFile.append(itemID);
|
cacheFile.append(itemID);
|
||||||
cacheFile.append(CACHE_FILE);
|
cacheFile.append(self.pdfConverterCacheFile);
|
||||||
return cacheFile;
|
return cacheFile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -237,9 +237,20 @@ Zotero.ItemTreeView.prototype.notify = function(action, type, ids)
|
||||||
var madeChanges = false;
|
var madeChanges = false;
|
||||||
var sort = false;
|
var sort = false;
|
||||||
|
|
||||||
this.selection.selectEventsSuppressed = true;
|
|
||||||
var savedSelection = this.saveSelection();
|
var savedSelection = this.saveSelection();
|
||||||
|
|
||||||
|
// If refreshing a single item, just unselect and reselect it
|
||||||
|
if (action == 'refresh') {
|
||||||
|
if (savedSelection.length == 1 && savedSelection[0] == ids[0]) {
|
||||||
|
this.selection.clearSelection();
|
||||||
|
this.rememberSelection(savedSelection);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.selection.selectEventsSuppressed = true;
|
||||||
|
|
||||||
// See if we're in the active window
|
// See if we're in the active window
|
||||||
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
|
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
|
||||||
.getService(Components.interfaces.nsIWindowMediator);
|
.getService(Components.interfaces.nsIWindowMediator);
|
||||||
|
|
|
@ -82,7 +82,7 @@ Zotero.Notifier = new function(){
|
||||||
* Possible values:
|
* Possible values:
|
||||||
*
|
*
|
||||||
* event: 'add', 'modify', 'delete', 'move' ('c', for changing parent),
|
* event: 'add', 'modify', 'delete', 'move' ('c', for changing parent),
|
||||||
* 'remove' (ci, it)
|
* 'remove' (ci, it), 'refresh'
|
||||||
* type - 'collection', 'search', 'item', 'collection-item', 'item-tag', 'tag'
|
* type - 'collection', 'search', 'item', 'collection-item', 'item-tag', 'tag'
|
||||||
* ids - single id or array of ids
|
* ids - single id or array of ids
|
||||||
*
|
*
|
||||||
|
|
|
@ -119,15 +119,6 @@ Zotero.Schema = new function(){
|
||||||
var up2 = _updateSchema('system');
|
var up2 = _updateSchema('system');
|
||||||
var up3 = _updateSchema('scrapers');
|
var up3 = _updateSchema('scrapers');
|
||||||
|
|
||||||
// Rebuild fulltext cache if necessary
|
|
||||||
if (Zotero.Fulltext.cacheIsOutdated()){
|
|
||||||
try {
|
|
||||||
Zotero.Fulltext.rebuildCache();
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
Components.utils.reportError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Zotero.DB.commitTransaction();
|
Zotero.DB.commitTransaction();
|
||||||
}
|
}
|
||||||
catch(e){
|
catch(e){
|
||||||
|
@ -1105,6 +1096,8 @@ Zotero.Schema = new function(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 1.0.0b4.r5
|
||||||
|
|
||||||
if (i==34) {
|
if (i==34) {
|
||||||
Zotero.DB.query("ALTER TABLE annotations ADD collapsed BOOL");
|
Zotero.DB.query("ALTER TABLE annotations ADD collapsed BOOL");
|
||||||
Zotero.DB.query("ALTER TABLE annotations ADD dateModified DATETIME");
|
Zotero.DB.query("ALTER TABLE annotations ADD dateModified DATETIME");
|
||||||
|
@ -1112,6 +1105,23 @@ Zotero.Schema = new function(){
|
||||||
Zotero.DB.query("UPDATE annotations SET dateModified = DATETIME('now')");
|
Zotero.DB.query("UPDATE annotations SET dateModified = DATETIME('now')");
|
||||||
Zotero.DB.query("UPDATE highlights SET dateModified = DATETIME('now')");
|
Zotero.DB.query("UPDATE highlights SET dateModified = DATETIME('now')");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (i==35) {
|
||||||
|
Zotero.DB.query("CREATE TABLE fulltextItemWords (\n wordID INT,\n itemID INT,\n PRIMARY KEY (wordID, itemID),\n FOREIGN KEY (wordID) REFERENCES fulltextWords(wordID),\n FOREIGN KEY (itemID) REFERENCES items(itemID)\n);");
|
||||||
|
Zotero.DB.query("INSERT INTO fulltextItemWords SELECT * FROM fulltextItems");
|
||||||
|
Zotero.DB.query("DROP TABLE fulltextItems");
|
||||||
|
Zotero.DB.query("CREATE TABLE fulltextItems (\n itemID INT,\n version INT,\n PRIMARY KEY (itemID),\n FOREIGN KEY (itemID) REFERENCES items(itemID)\n);");
|
||||||
|
Zotero.DB.query("INSERT INTO fulltextItems SELECT DISTINCT itemID, 1 FROM fulltextItemWords");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i==36) {
|
||||||
|
Zotero.DB.query("ALTER TABLE fulltextItems ADD indexedPages INT");
|
||||||
|
Zotero.DB.query("ALTER TABLE fulltextItems ADD totalPages INT");
|
||||||
|
Zotero.DB.query("ALTER TABLE fulltextItems ADD indexedChars INT");
|
||||||
|
Zotero.DB.query("ALTER TABLE fulltextItems ADD totalChars INT");
|
||||||
|
Zotero.DB.query("DELETE FROM version WHERE schema='fulltext'");
|
||||||
|
Zotero.DB.query("VACUUM");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateSchema('userdata');
|
_updateSchema('userdata');
|
||||||
|
|
|
@ -1354,7 +1354,7 @@ Zotero.SearchConditions = new function(){
|
||||||
contains: true,
|
contains: true,
|
||||||
doesNotContain: true
|
doesNotContain: true
|
||||||
},
|
},
|
||||||
table: 'fulltextItems',
|
table: 'fulltextItemWords',
|
||||||
field: 'word',
|
field: 'word',
|
||||||
special: true
|
special: true
|
||||||
},
|
},
|
||||||
|
|
|
@ -122,6 +122,7 @@ var Zotero = new function(){
|
||||||
this.platform = win.navigator.platform;
|
this.platform = win.navigator.platform;
|
||||||
this.isMac = (this.platform.substr(0, 3) == "Mac");
|
this.isMac = (this.platform.substr(0, 3) == "Mac");
|
||||||
this.isWin = (this.platform.substr(0, 3) == "Win");
|
this.isWin = (this.platform.substr(0, 3) == "Win");
|
||||||
|
this.isLinux = (this.platform.substr(0, 5) == "Linux");
|
||||||
|
|
||||||
// Locale
|
// Locale
|
||||||
var ph = Components.classes["@mozilla.org/network/protocol;1?name=http"].
|
var ph = Components.classes["@mozilla.org/network/protocol;1?name=http"].
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
<!ENTITY zotero.preferences.title "Zotero Preferences">
|
<!ENTITY zotero.preferences.title "Zotero Preferences">
|
||||||
|
|
||||||
|
<!ENTITY zotero.preferences.default "Default:">
|
||||||
|
|
||||||
<!ENTITY zotero.preferences.prefpane.general "General">
|
<!ENTITY zotero.preferences.prefpane.general "General">
|
||||||
|
|
||||||
<!ENTITY zotero.preferences.userInterface "User Interface">
|
<!ENTITY zotero.preferences.userInterface "User Interface">
|
||||||
|
@ -27,6 +29,13 @@
|
||||||
<!ENTITY zotero.preferences.openurl.server "Resolver:">
|
<!ENTITY zotero.preferences.openurl.server "Resolver:">
|
||||||
<!ENTITY zotero.preferences.openurl.version "Version:">
|
<!ENTITY zotero.preferences.openurl.version "Version:">
|
||||||
|
|
||||||
|
<!ENTITY zotero.preferences.prefpane.search "Search">
|
||||||
|
<!ENTITY zotero.preferences.search.fulltextCache "Full-Text Cache">
|
||||||
|
<!ENTITY zotero.preferences.search.pdfIndexing "PDF Indexing">
|
||||||
|
<!ENTITY zotero.preferences.search.indexStats "Index Statistics">
|
||||||
|
|
||||||
|
<!ENTITY zotero.preferences.fulltext.textMaxLength "Maximum characters to index per file:">
|
||||||
|
<!ENTITY zotero.preferences.fulltext.pdfMaxPages "Maximum pages to index per file:">
|
||||||
|
|
||||||
<!ENTITY zotero.preferences.prefpane.export "Export">
|
<!ENTITY zotero.preferences.prefpane.export "Export">
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
general.error = Error
|
general.error = Error
|
||||||
general.warning = Warning
|
general.warning = Warning
|
||||||
general.dontShowWarningAgain = Don't show this warning again.
|
general.dontShowWarningAgain = Don't show this warning again.
|
||||||
|
general.browserIsOffline = %S is currently in offline mode.
|
||||||
general.locate = Locate...
|
general.locate = Locate...
|
||||||
general.restartRequired = Restart Required
|
general.restartRequired = Restart Required
|
||||||
general.restartRequiredForChange = Firefox must be restarted for the change to take effect.
|
general.restartRequiredForChange = Firefox must be restarted for the change to take effect.
|
||||||
|
@ -10,6 +11,12 @@ general.restartLater = Restart later
|
||||||
general.errorHasOccurred = An error has occurred.
|
general.errorHasOccurred = An error has occurred.
|
||||||
general.restartFirefox = Please restart Firefox.
|
general.restartFirefox = Please restart Firefox.
|
||||||
general.restartFirefoxAndTryAgain = Please restart Firefox and try again.
|
general.restartFirefoxAndTryAgain = Please restart Firefox and try again.
|
||||||
|
general.checkForUpdate = Check for update
|
||||||
|
general.install = Install
|
||||||
|
general.updateAvailable = Update Available
|
||||||
|
general.upgrade = Upgrade
|
||||||
|
general.yes = Yes
|
||||||
|
general.no = No
|
||||||
|
|
||||||
upgrade.failed = Upgrading of the Zotero database failed:
|
upgrade.failed = Upgrading of the Zotero database failed:
|
||||||
upgrade.advanceMessage = Press %S to upgrade now.
|
upgrade.advanceMessage = Press %S to upgrade now.
|
||||||
|
@ -74,6 +81,8 @@ 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...
|
||||||
pane.items.menu.generateReport.multiple = Generate Report from Selected Items...
|
pane.items.menu.generateReport.multiple = Generate Report from Selected Items...
|
||||||
|
pane.items.menu.reindexItem = Reindex Item
|
||||||
|
pane.items.menu.reindexItem.multiple = Reindex Items
|
||||||
|
|
||||||
pane.item.selected.zero = No items selected
|
pane.item.selected.zero = No items selected
|
||||||
pane.item.selected.multiple = %S items selected
|
pane.item.selected.multiple = %S items selected
|
||||||
|
@ -313,6 +322,29 @@ zotero.preferences.update.error = Error
|
||||||
zotero.preferences.openurl.resolversFound.zero = %S resolvers found
|
zotero.preferences.openurl.resolversFound.zero = %S resolvers found
|
||||||
zotero.preferences.openurl.resolversFound.singular = %S resolver found
|
zotero.preferences.openurl.resolversFound.singular = %S resolver found
|
||||||
zotero.preferences.openurl.resolversFound.plural = %S resolvers found
|
zotero.preferences.openurl.resolversFound.plural = %S resolvers found
|
||||||
|
zotero.preferences.search.rebuildIndex = Rebuild Index
|
||||||
|
zotero.preferences.search.rebuildWarning = Do you want to rebuild the entire index? This may take a while.\n\nTo index only items that haven't been indexed, use %S.
|
||||||
|
zotero.preferences.search.clearIndex = Clear Index
|
||||||
|
zotero.preferences.search.clearWarning = After clearing the index, attachment content will no longer be searchable.\n\nWeb link attachments cannot be reindexed without revisiting the page. To leave web links indexed, choose %S.
|
||||||
|
zotero.preferences.search.clearNonLinkedURLs = Clear All Except Web Links
|
||||||
|
zotero.preferences.search.indexUnindexed = Index Unindexed Items
|
||||||
|
zotero.preferences.search.pdf.toolRegistered = %S is installed
|
||||||
|
zotero.preferences.search.pdf.toolNotRegistered = %S is NOT installed
|
||||||
|
zotero.preferences.search.pdf.toolsRequired = PDF indexing requires the %1$S and %2$S utilities from the %3$S project.
|
||||||
|
zotero.preferences.search.pdf.automaticInstall = Zotero can automatically download and install these applications from zotero.org for certain platforms.
|
||||||
|
zotero.preferences.search.pdf.advancedUsers = Advanced users may wish to view the %S for manual installation instructions.
|
||||||
|
zotero.preferences.search.pdf.documentationLink = documentation
|
||||||
|
zotero.preferences.search.pdf.checkForInstaller = Check for installer
|
||||||
|
zotero.preferences.search.pdf.downloading = Downloading...
|
||||||
|
zotero.preferences.search.pdf.toolDownloadsNotAvailable = The %S utilities are not currently available for your platform via zotero.org.
|
||||||
|
zotero.preferences.search.pdf.viewManualInstructions = View the documentation for manual installation instructions.
|
||||||
|
zotero.preferences.search.pdf.availableDownloads = Available downloads for %1$S from %2$S:
|
||||||
|
zotero.preferences.search.pdf.availableUpdates = Available updates for %1$S from %2$S:
|
||||||
|
zotero.preferences.search.pdf.toolVersionPlatform = %1$S version %2$S
|
||||||
|
zotero.preferences.search.pdf.zoteroCanInstallVersion = Zotero can automatically install it into the Zotero data directory.
|
||||||
|
zotero.preferences.search.pdf.zoteroCanInstallVersions = Zotero can automatically install these applications into the Zotero data directory.
|
||||||
|
zotero.preferences.search.pdf.toolsDownloadError = An error occurred while attempting to download the %S utilities from zotero.org.
|
||||||
|
zotero.preferences.search.pdf.tryAgainOrViewManualInstructions = Please try again later, or view the documentation for manual installation instructions.
|
||||||
zotero.preferences.export.quickCopy.bibStyles = Bibliographic Styles
|
zotero.preferences.export.quickCopy.bibStyles = Bibliographic 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 copy selected references to the clipboard by pressing a shortcut key (%S) or dragging items into a text box on a web page.
|
zotero.preferences.export.quickCopy.instructions = Quick Copy allows you to copy selected references to the clipboard by pressing a shortcut key (%S) or dragging items into a text box on a web page.
|
||||||
|
@ -371,6 +403,9 @@ searchConditions.fulltextContent = Attachment Content
|
||||||
searchConditions.programmingLanguage = Programming Language
|
searchConditions.programmingLanguage = Programming Language
|
||||||
searchConditions.fileTypeID = Attachment File Type
|
searchConditions.fileTypeID = Attachment File Type
|
||||||
|
|
||||||
|
fulltext.indexState.indexed = Indexed
|
||||||
|
fulltext.indexState.unavailable = Unknown
|
||||||
|
fulltext.indexState.partial = Partial
|
||||||
|
|
||||||
exportOptions.exportNotes = Export Notes
|
exportOptions.exportNotes = Export Notes
|
||||||
exportOptions.exportFileData = Export Files
|
exportOptions.exportFileData = Export Files
|
||||||
|
|
BIN
chrome/skin/default/zotero/arrow_refresh.png
Executable file
BIN
chrome/skin/default/zotero/arrow_refresh.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 685 B |
|
@ -233,6 +233,27 @@
|
||||||
-moz-box-flex: 1;
|
-moz-box-flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Reindex button in attachment pane */
|
||||||
|
#zotero-attachment-index-box
|
||||||
|
{
|
||||||
|
-moz-box-align: center;
|
||||||
|
}
|
||||||
|
#zotero-attachment-reindex
|
||||||
|
{
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
list-style-image: url(chrome://zotero/skin/arrow_refresh.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#zotero-attachment-reindex .toolbarbutton-icon
|
||||||
|
{
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#zotero-go-to-url[disabled=true], #zotero-openurl[disabled=true]
|
#zotero-go-to-url[disabled=true], #zotero-openurl[disabled=true]
|
||||||
{
|
{
|
||||||
list-style-image: url('chrome://zotero/skin/toolbar-go-arrow-disabled.png');
|
list-style-image: url('chrome://zotero/skin/toolbar-go-arrow-disabled.png');
|
||||||
|
@ -250,6 +271,18 @@
|
||||||
min-height: 1.25em;
|
min-height: 1.25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#zotero-attachment-index-box
|
||||||
|
{
|
||||||
|
-moz-box-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#zotero-attachment-index-box > button
|
||||||
|
{
|
||||||
|
font-size: .95em;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#zotero-splitter
|
#zotero-splitter
|
||||||
{
|
{
|
||||||
border-top: none;
|
border-top: none;
|
||||||
|
|
|
@ -3,6 +3,16 @@ prefwindow .chromeclass-toolbar
|
||||||
display: -moz-box !important; /* Ignore toolbar collapse button on OS X */
|
display: -moz-box !important; /* Ignore toolbar collapse button on OS X */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Prevent bugs in automatic prefpane sizing in Firefox 2.0
|
||||||
|
From http://forums.mozillazine.org/viewtopic.php?p=2883233&sid=e1285f81ea9c824363802ea5ca96c9b2
|
||||||
|
*/
|
||||||
|
prefwindow {
|
||||||
|
width: 45em;
|
||||||
|
}
|
||||||
|
prefwindow > prefpane > vbox.content-box {
|
||||||
|
height: 42em;
|
||||||
|
}
|
||||||
|
|
||||||
radio[pane]
|
radio[pane]
|
||||||
{
|
{
|
||||||
min-width: 5.5em;
|
min-width: 5.5em;
|
||||||
|
@ -11,46 +21,64 @@ radio[pane]
|
||||||
-moz-box-pack: end;
|
-moz-box-pack: end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* General pane icon */
|
/* Remove extraneous padding */
|
||||||
|
vbox > *:first-child
|
||||||
|
{
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
vbox > *:last-child
|
||||||
|
{
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
hbox > *:first-child
|
||||||
|
{
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
hbox
|
||||||
|
{
|
||||||
|
-moz-outline: 1px dashed green;
|
||||||
|
}
|
||||||
|
vbox
|
||||||
|
{
|
||||||
|
-moz-outline: 1px dashed yellow;
|
||||||
|
}
|
||||||
|
label
|
||||||
|
{
|
||||||
|
-moz-outline: 1px dashed pink;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Links within messages */
|
||||||
|
label label[class=text-link]
|
||||||
|
{
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* General pane */
|
||||||
radio[pane=zotero-prefpane-general]
|
radio[pane=zotero-prefpane-general]
|
||||||
{
|
{
|
||||||
list-style-image: url("chrome://zotero/skin/prefs-general.png");
|
list-style-image: url("chrome://zotero/skin/prefs-general.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
grid row:not(:first-child)
|
||||||
* Export pane icon
|
|
||||||
*/
|
|
||||||
radio[pane=zotero-prefpane-export]
|
|
||||||
{
|
{
|
||||||
list-style-image: url("chrome://zotero/skin/prefs-export.png");
|
margin-top: .3em;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Shortcut Keys pane icon
|
|
||||||
*
|
|
||||||
* Use the Gear icon until we find a keyboard icon
|
|
||||||
*/
|
|
||||||
radio[pane=zotero-prefpane-keys]
|
|
||||||
{
|
|
||||||
list-style-image: url("chrome://zotero/skin/prefs-keys.png");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Advanced pane icon
|
|
||||||
*
|
|
||||||
* Use the Gear icon until we find a better icon
|
|
||||||
*/
|
|
||||||
radio[pane=zotero-prefpane-advanced]
|
|
||||||
{
|
|
||||||
list-style-image: url("chrome://zotero/skin/prefs-advanced.png");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* General pane */
|
|
||||||
grid row hbox:first-child
|
grid row hbox:first-child
|
||||||
{
|
{
|
||||||
-moz-box-pack: end;
|
-moz-box-pack: end; /* Right-justify left column */
|
||||||
|
}
|
||||||
|
|
||||||
|
#position-menu-box-label, #position-menu-box
|
||||||
|
{
|
||||||
|
-moz-box-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
#fontSize
|
#fontSize
|
||||||
|
@ -90,7 +118,51 @@ grid row hbox:first-child
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Search pane
|
||||||
|
*/
|
||||||
|
radio[pane=zotero-prefpane-search]
|
||||||
|
{
|
||||||
|
list-style-image: url("chrome://zotero/skin/prefs-search.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
#zotero-prefpane-search groupbox > label, #zotero-prefpane-search groupbox > vbox, #zotero-prefpane-search groupbox > hbox
|
||||||
|
{
|
||||||
|
margin: .5em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#zotero-prefpane-search groupbox > label:first-child
|
||||||
|
{
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pdfinfo-status
|
||||||
|
{
|
||||||
|
margin-top: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fulltext-settings hbox, #pdftools-settings hbox
|
||||||
|
{
|
||||||
|
-moz-box-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fulltext-settings row > hbox:last-child, #pdftools-settings row > hbox:last-child
|
||||||
|
{
|
||||||
|
margin-left: .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fulltext-stats row > label:first-child
|
||||||
|
{
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Export pane */
|
/* Export pane */
|
||||||
|
radio[pane=zotero-prefpane-export]
|
||||||
|
{
|
||||||
|
list-style-image: url("chrome://zotero/skin/prefs-export.png");
|
||||||
|
}
|
||||||
|
|
||||||
#quickCopy-instructions, #zotero-prefpane-export vbox {
|
#quickCopy-instructions, #zotero-prefpane-export vbox {
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
}
|
}
|
||||||
|
@ -119,6 +191,11 @@ grid row hbox:first-child
|
||||||
|
|
||||||
|
|
||||||
/* Shortcut Keys pane */
|
/* Shortcut Keys pane */
|
||||||
|
radio[pane=zotero-prefpane-keys]
|
||||||
|
{
|
||||||
|
list-style-image: url("chrome://zotero/skin/prefs-keys.png");
|
||||||
|
}
|
||||||
|
|
||||||
#zotero-prefpane-keys row
|
#zotero-prefpane-keys row
|
||||||
{
|
{
|
||||||
-moz-box-align: center;
|
-moz-box-align: center;
|
||||||
|
@ -139,3 +216,12 @@ grid row hbox:first-child
|
||||||
margin: .75em 0;
|
margin: .75em 0;
|
||||||
font-size: .85em;
|
font-size: .85em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Advanced pane
|
||||||
|
*/
|
||||||
|
radio[pane=zotero-prefpane-advanced]
|
||||||
|
{
|
||||||
|
list-style-image: url("chrome://zotero/skin/prefs-advanced.png");
|
||||||
|
}
|
||||||
|
|
BIN
chrome/skin/default/zotero/prefs-search.png
Normal file
BIN
chrome/skin/default/zotero/prefs-search.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
22
userdata.sql
22
userdata.sql
|
@ -1,4 +1,4 @@
|
||||||
-- 34
|
-- 36
|
||||||
|
|
||||||
-- This file creates tables containing user-specific data -- any changes
|
-- This file creates tables containing user-specific data -- any changes
|
||||||
-- to existing tables made here must be mirrored in transition steps in
|
-- to existing tables made here must be mirrored in transition steps in
|
||||||
|
@ -205,18 +205,32 @@ CREATE TABLE IF NOT EXISTS savedSearchConditions (
|
||||||
FOREIGN KEY (savedSearchID) REFERENCES savedSearches(savedSearchID)
|
FOREIGN KEY (savedSearchID) REFERENCES savedSearches(savedSearchID)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS fulltextItems (
|
||||||
|
itemID INT,
|
||||||
|
version INT,
|
||||||
|
indexedPages INT,
|
||||||
|
totalPages INT,
|
||||||
|
indexedChars INT,
|
||||||
|
totalChars INT,
|
||||||
|
PRIMARY KEY (itemID),
|
||||||
|
FOREIGN KEY (itemID) REFERENCES items(itemID)
|
||||||
|
);
|
||||||
|
CREATE INDEX IF NOT EXISTS fulltextItems_version ON fulltextItems(version);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS fulltextWords (
|
CREATE TABLE IF NOT EXISTS fulltextWords (
|
||||||
wordID INTEGER PRIMARY KEY,
|
wordID INTEGER PRIMARY KEY,
|
||||||
word TEXT UNIQUE
|
word TEXT UNIQUE
|
||||||
);
|
);
|
||||||
CREATE INDEX IF NOT EXISTS fulltextWords_word ON fulltextWords(word);
|
CREATE INDEX IF NOT EXISTS fulltextWords_word ON fulltextWords(word);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS fulltextItems (
|
CREATE TABLE IF NOT EXISTS fulltextItemWords (
|
||||||
wordID INT,
|
wordID INT,
|
||||||
itemID INT,
|
itemID INT,
|
||||||
PRIMARY KEY (wordID, itemID)
|
PRIMARY KEY (wordID, itemID),
|
||||||
|
FOREIGN KEY (wordID) REFERENCES fulltextWords(wordID),
|
||||||
|
FOREIGN KEY (itemID) REFERENCES items(itemID)
|
||||||
);
|
);
|
||||||
CREATE INDEX IF NOT EXISTS fulltextItems_itemID ON fulltextItems(itemID);
|
CREATE INDEX IF NOT EXISTS fulltextItemWords_itemID ON fulltextItemWords(itemID);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS translators (
|
CREATE TABLE IF NOT EXISTS translators (
|
||||||
translatorID TEXT PRIMARY KEY,
|
translatorID TEXT PRIMARY KEY,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user