- 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.onCollectionSelected = onCollectionSelected;
|
||||
this.itemSelected = itemSelected;
|
||||
this.updateItemIndexedState = updateItemIndexedState;
|
||||
this.reindexItem = reindexItem;
|
||||
this.duplicateSelectedItem = duplicateSelectedItem;
|
||||
this.deleteSelectedItem = deleteSelectedItem;
|
||||
this.deleteSelectedCollection = deleteSelectedCollection;
|
||||
|
@ -852,6 +854,20 @@ var ZoteroPane = new function()
|
|||
|
||||
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');
|
||||
noteEditor.item = null;
|
||||
noteEditor.note = item.ref;
|
||||
|
@ -869,7 +885,7 @@ var ZoteroPane = new function()
|
|||
document.getElementById('zotero-item-pane-content').selectedIndex = 0;
|
||||
|
||||
var label = document.getElementById('zotero-view-selected-label');
|
||||
|
||||
|
||||
if (this.itemsView && this.itemsView.selection.count) {
|
||||
label.value = Zotero.getString('pane.item.selected.multiple', this.itemsView.selection.count);
|
||||
}
|
||||
|
@ -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() {
|
||||
var newItemID = this.getSelectedItems()[0].clone();
|
||||
var newItem = Zotero.Items.get(newItemID);
|
||||
|
@ -1280,7 +1355,9 @@ var ZoteroPane = new function()
|
|||
sep3: 9,
|
||||
exportItems: 10,
|
||||
createBib: 11,
|
||||
loadReport: 12
|
||||
loadReport: 12,
|
||||
sep4: 13,
|
||||
reindexItem: 14
|
||||
};
|
||||
|
||||
var menu = document.getElementById('zotero-itemmenu');
|
||||
|
@ -1297,6 +1374,22 @@ var ZoteroPane = new function()
|
|||
var multiple = '.multiple';
|
||||
hide.push(m.showInLibrary, m.sep1, m.addNote, m.attachSnapshot,
|
||||
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
|
||||
else
|
||||
|
@ -1324,12 +1417,21 @@ var ZoteroPane = new function()
|
|||
|
||||
if (item.isAttachment()) {
|
||||
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 {
|
||||
show.push(m.duplicateItem);
|
||||
hide.push(m.sep4, m.reindexItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
// No items selected
|
||||
else
|
||||
{
|
||||
// Show in Library
|
||||
|
@ -1342,7 +1444,7 @@ var ZoteroPane = new function()
|
|||
|
||||
disable.push(m.showInLibrary, m.duplicateItem, m.deleteItem,
|
||||
m.deleteFromLibrary, m.exportItems, m.createBib, m.loadReport);
|
||||
hide.push(m.addNote, m.attachSnapshot, m.attachLink, m.sep2);
|
||||
hide.push(m.addNote, m.attachSnapshot, m.attachLink, m.sep2, m.sep4, m.reindexItem);
|
||||
}
|
||||
|
||||
// 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.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.reindexItem].setAttribute('label', Zotero.getString('pane.items.menu.reindexItem' + multiple));
|
||||
|
||||
for (var i in disable)
|
||||
{
|
||||
|
|
|
@ -101,6 +101,8 @@
|
|||
<menuitem oncommand="Zotero_File_Interface.exportItems();"/>
|
||||
<menuitem oncommand="Zotero_File_Interface.bibliographyFromItems();"/>
|
||||
<menuitem oncommand="Zotero_Report_Interface.loadItemReport()"/>
|
||||
<menuseparator/>
|
||||
<menuitem oncommand="ZoteroPane.reindexItem();"/>
|
||||
</popup>
|
||||
</popupset>
|
||||
|
||||
|
@ -305,10 +307,17 @@
|
|||
<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()"/>
|
||||
</hbox>
|
||||
<vbox>
|
||||
<label id="zotero-attachment-url" class="text-link" crop="end" onclick="ZoteroPane.loadURI(this.value, event)"/>
|
||||
<label id="zotero-attachment-accessed"/>
|
||||
</vbox>
|
||||
<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-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"/>
|
||||
</vbox>
|
||||
</deck>
|
||||
|
|
|
@ -33,6 +33,7 @@ function init()
|
|||
|
||||
populateQuickCopyList();
|
||||
updateQuickCopyInstructions();
|
||||
initSearchPane();
|
||||
}
|
||||
|
||||
|
||||
|
@ -261,9 +262,9 @@ function refreshQuickCopySiteList() {
|
|||
treeitem.appendChild(treerow);
|
||||
treechildren.appendChild(treeitem);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function deleteSelectedQuickCopySite() {
|
||||
var tree = document.getElementById('quickCopy-siteSettings');
|
||||
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()
|
||||
{
|
||||
|
|
|
@ -66,10 +66,10 @@ To add a new preference:
|
|||
|
||||
<rows>
|
||||
<row>
|
||||
<hbox>
|
||||
<hbox id="position-menu-box-label">
|
||||
<label value="&zotero.preferences.position;" control="positionMenu"/>
|
||||
</hbox>
|
||||
<hbox>
|
||||
<hbox id="position-menu-box">
|
||||
<menulist id="positionMenu" preference="pref-zoteroPaneOnTop">
|
||||
<menupopup>
|
||||
<menuitem label="&zotero.preferences.position.above;" value="true"/>
|
||||
|
@ -151,6 +151,104 @@ To add a new preference:
|
|||
</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;">
|
||||
<preferences>
|
||||
<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.getFileBaseNameFromItem = getFileBaseNameFromItem;
|
||||
this.createDirectoryForItem = createDirectoryForItem;
|
||||
this.getStorageDirectory = getStorageDirectory;
|
||||
this.getPath = getPath;
|
||||
|
||||
var self = this;
|
||||
|
@ -499,12 +500,14 @@ Zotero.Attachments = new function(){
|
|||
|
||||
if (mimeType == 'application/pdf') {
|
||||
var f = function() {
|
||||
Zotero.Fulltext.indexPDF(file, itemID);;
|
||||
Zotero.Fulltext.indexPDF(file, itemID);
|
||||
Zotero.Notifier.trigger('refresh', 'item', itemID);
|
||||
};
|
||||
}
|
||||
else {
|
||||
var f = function() {
|
||||
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
|
||||
*/
|
||||
function createDirectoryForItem(itemID) {
|
||||
var dir = Zotero.getStorageDirectory();
|
||||
dir.append(itemID);
|
||||
var dir = this.getStorageDirectory(itemID);
|
||||
if (!dir.exists()) {
|
||||
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
|
||||
* for files outside the storage directory
|
||||
* Gets a relative descriptor for imported attachments and a persistent
|
||||
* descriptor for files outside the storage directory
|
||||
*/
|
||||
function getPath(file, linkMode) {
|
||||
if (linkMode == self.LINK_MODE_IMPORTED_URL ||
|
||||
|
|
|
@ -25,6 +25,7 @@ Zotero.File = new function(){
|
|||
this.getClosestDirectory = getClosestDirectory;
|
||||
this.getSample = getSample;
|
||||
this.getContents = getContents;
|
||||
this.putContents = putContents;
|
||||
this.getCharsetFromFile = getCharsetFromFile;
|
||||
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
|
||||
*/
|
||||
|
|
|
@ -25,11 +25,10 @@ Zotero.Fulltext = new function(){
|
|||
const CACHE_FILE = '.zotero-ft-cache';
|
||||
|
||||
this.init = init;
|
||||
this.registerPDFToText = registerPDFToText;
|
||||
this.cacheIsOutdated = cacheIsOutdated;
|
||||
this.rebuildCache = rebuildCache;
|
||||
this.registerPDFTool = registerPDFTool;
|
||||
this.pdfConverterIsRegistered = pdfConverterIsRegistered;
|
||||
this.pdfInfoIsRegistered = pdfInfoIsRegistered;
|
||||
this.isCachedMIMEType = isCachedMIMEType;
|
||||
this.indexWord = indexWord;
|
||||
this.indexWords = indexWords;
|
||||
this.indexDocument = indexDocument;
|
||||
this.indexString = indexString;
|
||||
|
@ -39,16 +38,62 @@ Zotero.Fulltext = new function(){
|
|||
this.findTextInFile = findTextInFile;
|
||||
this.findTextInItems = findTextInItems;
|
||||
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.purgeUnusedWords = purgeUnusedWords;
|
||||
this.HTMLToText = HTMLToText;
|
||||
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() {
|
||||
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
|
||||
* e.g. "Win32", "Linux-i686", "MacPPC", "MacIntel", etc.
|
||||
*/
|
||||
function registerPDFToText() {
|
||||
function registerPDFTool(tool) {
|
||||
var errMsg = false;
|
||||
var exec = Zotero.getZoteroDirectory();
|
||||
|
||||
var fileName = 'pdftotext-' + Zotero.platform.replace(' ', '-');
|
||||
if (Zotero.isWin) {
|
||||
fileName += '.exe';
|
||||
switch (tool) {
|
||||
case 'converter':
|
||||
var toolName = this.pdfConverterName;
|
||||
var fileName = _pdfConverterFileName
|
||||
break;
|
||||
|
||||
case 'info':
|
||||
var toolName = this.pdfInfoName;
|
||||
var fileName = _pdfInfoFileName
|
||||
break;
|
||||
|
||||
default:
|
||||
throw ("Invalid PDF tool type '" + tool + "' in Zotero.Fulltext.registerPDFTool()");
|
||||
}
|
||||
|
||||
var errMsg = false;
|
||||
|
||||
exec.append(fileName);
|
||||
if (exec.exists()) {
|
||||
// DEBUG: I'm not sure isSymlink() actually works on any platforms
|
||||
if (exec.isSymlink()) {
|
||||
exec = exec.target;
|
||||
if (!exec.target) {
|
||||
errMsg = fileName + ' symlink target not found';
|
||||
exec = null;
|
||||
}
|
||||
else {
|
||||
_pdftotext = exec;
|
||||
}
|
||||
}
|
||||
else {
|
||||
_pdftotext = exec;
|
||||
}
|
||||
}
|
||||
else {
|
||||
exec = null;
|
||||
errMsg = fileName + ' not found';
|
||||
}
|
||||
|
||||
if (_pdftotext) {
|
||||
Zotero.debug('pdftotext registered at ' + _pdftotext.path);
|
||||
}
|
||||
else {
|
||||
_pdftotext = null;
|
||||
Zotero.debug(errMsg + ' -- PDF indexing disabled');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function cacheIsOutdated(){
|
||||
var sql = "SELECT version FROM version WHERE schema='fulltext'";
|
||||
return Zotero.DB.valueQuery(sql) < FULLTEXT_VERSION;
|
||||
}
|
||||
|
||||
|
||||
function rebuildCache(){
|
||||
Zotero.DB.beginTransaction();
|
||||
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);
|
||||
if (!exec) {
|
||||
if (tool == 'converter') {
|
||||
Zotero.debug(errMsg + ' -- PDF indexing disabled');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Zotero.DB.commitTransaction();
|
||||
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 pdfConverterIsRegistered() {
|
||||
return !!_pdfConverter;
|
||||
}
|
||||
|
||||
|
||||
function pdfInfoIsRegistered() {
|
||||
return !!_pdfInfo;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Returns true if MIME type is converted to text and cached before indexing
|
||||
* (e.g. application/pdf is run through pdftotext)
|
||||
*/
|
||||
function isCachedMIMEType(mimeType) {
|
||||
switch (mimeType) {
|
||||
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
|
||||
*/
|
||||
|
@ -179,9 +223,12 @@ Zotero.Fulltext = new function(){
|
|||
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
|
||||
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){
|
||||
if (existing['_' + word]){
|
||||
|
@ -206,19 +253,26 @@ Zotero.Fulltext = new function(){
|
|||
|
||||
|
||||
function indexString(text, charset, itemID){
|
||||
var words = semanticSplitter(text, charset);
|
||||
|
||||
Zotero.DB.beginTransaction();
|
||||
|
||||
this.clearItemWords(itemID);
|
||||
this.indexWords(itemID, words);
|
||||
|
||||
/*
|
||||
var sql = "REPLACE INTO fulltextContent (itemID, textContent) VALUES (?,?)";
|
||||
Zotero.DB.query(sql, [itemID, {string:text}]);
|
||||
*/
|
||||
|
||||
Zotero.DB.commitTransaction();
|
||||
try {
|
||||
Zotero.UnresponsiveScriptIndicator.disable();
|
||||
|
||||
var words = semanticSplitter(text, charset);
|
||||
|
||||
Zotero.DB.beginTransaction();
|
||||
|
||||
this.clearItemWords(itemID);
|
||||
this.indexWords(itemID, words);
|
||||
|
||||
/*
|
||||
var sql = "REPLACE INTO fulltextContent (itemID, textContent) VALUES (?,?)";
|
||||
Zotero.DB.query(sql, [itemID, {string:text}]);
|
||||
*/
|
||||
|
||||
Zotero.DB.commitTransaction();
|
||||
}
|
||||
finally {
|
||||
Zotero.UnresponsiveScriptIndicator.enable();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -241,20 +295,23 @@ Zotero.Fulltext = new function(){
|
|||
|
||||
var text = document.body.innerHTML;
|
||||
|
||||
var max = Zotero.Prefs.get('fulltext.textMaxLength');
|
||||
if (text.length > max) {
|
||||
Zotero.debug('Only indexing first ' + max + ' characters of item '
|
||||
var maxLength = Zotero.Prefs.get('fulltext.textMaxLength');
|
||||
if (text.length > maxLength) {
|
||||
Zotero.debug('Only indexing first ' + maxLength + ' characters of item '
|
||||
+ itemID + ' in indexDocument()');
|
||||
text = text.substr(0, max);
|
||||
text = text.substr(0, maxLength);
|
||||
}
|
||||
|
||||
text = text.replace(/(>)/g, '$1 ');
|
||||
text = this.HTMLToText(text);
|
||||
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()){
|
||||
Zotero.debug('File not found in indexFile()', 2);
|
||||
return false;
|
||||
|
@ -267,8 +324,22 @@ Zotero.Fulltext = new function(){
|
|||
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') {
|
||||
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/'){
|
||||
|
@ -283,23 +354,36 @@ Zotero.Fulltext = new function(){
|
|||
|
||||
Zotero.debug('Indexing file ' + file.path);
|
||||
|
||||
var maxLength = Zotero.Prefs.get('fulltext.textMaxLength');
|
||||
var text = Zotero.File.getContents(file, charset, maxLength);
|
||||
// Split elements to avoid word concatentation
|
||||
text = text.replace(/(>)/g, '$1 ');
|
||||
text = this.HTMLToText(text);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Run PDF through pdftotext to generate .zotero-ft-cache and pass the
|
||||
* text file back to indexFile()
|
||||
* Run PDF through pdfinfo and pdftotext to generate .zotero-ft-info
|
||||
* 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) {
|
||||
if (!_pdftotext) {
|
||||
function indexPDF(file, itemID, allPages) {
|
||||
if (!_pdfConverter) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -313,25 +397,63 @@ Zotero.Fulltext = new function(){
|
|||
else {
|
||||
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"].
|
||||
createInstance(Components.interfaces.nsIProcess);
|
||||
proc.init(_pdfInfo);
|
||||
|
||||
var args = [file.path, infoFile.path];
|
||||
proc.run(true, args, args.length);
|
||||
|
||||
var totalPages = this.getTotalPagesFromFile(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(_pdftotext);
|
||||
var maxPages = Zotero.Prefs.get('fulltext.pdfMaxPages');
|
||||
Zotero.debug('Running pdftotext -nopgbrk -l ' + maxPages +
|
||||
' "' + file.path + '" "' + cacheFile.path + '"');
|
||||
var args = ['-nopgbrk', '-l', maxPages, file.path, cacheFile.path];
|
||||
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()) {
|
||||
return this.indexFile(cacheFile, 'text/plain', 'utf-8', itemID);
|
||||
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') {
|
||||
items = [items];
|
||||
}
|
||||
|
@ -352,12 +474,9 @@ Zotero.Fulltext = new function(){
|
|||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -497,10 +616,273 @@ Zotero.Fulltext = new function(){
|
|||
|
||||
|
||||
function clearItemWords(itemID){
|
||||
Zotero.DB.beginTransaction();
|
||||
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
|
||||
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 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()) {
|
||||
case 'application/pdf':
|
||||
var cacheFile = _getItemCacheFile();
|
||||
|
@ -509,6 +891,22 @@ Zotero.Fulltext = new function(){
|
|||
}
|
||||
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(){
|
||||
var sql = "DELETE FROM fulltextWords WHERE wordID NOT IN "
|
||||
+ "(SELECT wordID FROM fulltextItems)";
|
||||
+ "(SELECT wordID FROM fulltextItemWords)";
|
||||
Zotero.DB.query(sql);
|
||||
}
|
||||
|
||||
|
@ -626,7 +1024,7 @@ Zotero.Fulltext = new function(){
|
|||
function _getItemCacheFile(itemID) {
|
||||
var cacheFile = Zotero.getStorageDirectory();
|
||||
cacheFile.append(itemID);
|
||||
cacheFile.append(CACHE_FILE);
|
||||
cacheFile.append(self.pdfConverterCacheFile);
|
||||
return cacheFile;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -237,9 +237,20 @@ Zotero.ItemTreeView.prototype.notify = function(action, type, ids)
|
|||
var madeChanges = false;
|
||||
var sort = false;
|
||||
|
||||
this.selection.selectEventsSuppressed = true;
|
||||
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
|
||||
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
|
||||
.getService(Components.interfaces.nsIWindowMediator);
|
||||
|
|
|
@ -82,7 +82,7 @@ Zotero.Notifier = new function(){
|
|||
* Possible values:
|
||||
*
|
||||
* 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'
|
||||
* ids - single id or array of ids
|
||||
*
|
||||
|
|
|
@ -119,15 +119,6 @@ Zotero.Schema = new function(){
|
|||
var up2 = _updateSchema('system');
|
||||
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();
|
||||
}
|
||||
catch(e){
|
||||
|
@ -1105,6 +1096,8 @@ Zotero.Schema = new function(){
|
|||
}
|
||||
}
|
||||
|
||||
// 1.0.0b4.r5
|
||||
|
||||
if (i==34) {
|
||||
Zotero.DB.query("ALTER TABLE annotations ADD collapsed BOOL");
|
||||
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 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');
|
||||
|
|
|
@ -1354,7 +1354,7 @@ Zotero.SearchConditions = new function(){
|
|||
contains: true,
|
||||
doesNotContain: true
|
||||
},
|
||||
table: 'fulltextItems',
|
||||
table: 'fulltextItemWords',
|
||||
field: 'word',
|
||||
special: true
|
||||
},
|
||||
|
|
|
@ -122,6 +122,7 @@ var Zotero = new function(){
|
|||
this.platform = win.navigator.platform;
|
||||
this.isMac = (this.platform.substr(0, 3) == "Mac");
|
||||
this.isWin = (this.platform.substr(0, 3) == "Win");
|
||||
this.isLinux = (this.platform.substr(0, 5) == "Linux");
|
||||
|
||||
// Locale
|
||||
var ph = Components.classes["@mozilla.org/network/protocol;1?name=http"].
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<!ENTITY zotero.preferences.title "Zotero Preferences">
|
||||
|
||||
<!ENTITY zotero.preferences.default "Default:">
|
||||
|
||||
<!ENTITY zotero.preferences.prefpane.general "General">
|
||||
|
||||
<!ENTITY zotero.preferences.userInterface "User Interface">
|
||||
|
@ -27,6 +29,13 @@
|
|||
<!ENTITY zotero.preferences.openurl.server "Resolver:">
|
||||
<!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">
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
general.error = Error
|
||||
general.warning = Warning
|
||||
general.dontShowWarningAgain = Don't show this warning again.
|
||||
general.browserIsOffline = %S is currently in offline mode.
|
||||
general.locate = Locate...
|
||||
general.restartRequired = Restart Required
|
||||
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.restartFirefox = Please restart Firefox.
|
||||
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.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.generateReport = Generate Report from Selected Item...
|
||||
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.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.singular = %S resolver 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.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.
|
||||
|
@ -371,6 +403,9 @@ searchConditions.fulltextContent = Attachment Content
|
|||
searchConditions.programmingLanguage = Programming Language
|
||||
searchConditions.fileTypeID = Attachment File Type
|
||||
|
||||
fulltext.indexState.indexed = Indexed
|
||||
fulltext.indexState.unavailable = Unknown
|
||||
fulltext.indexState.partial = Partial
|
||||
|
||||
exportOptions.exportNotes = Export Notes
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/* 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]
|
||||
{
|
||||
list-style-image: url('chrome://zotero/skin/toolbar-go-arrow-disabled.png');
|
||||
|
@ -250,6 +271,18 @@
|
|||
min-height: 1.25em;
|
||||
}
|
||||
|
||||
#zotero-attachment-index-box
|
||||
{
|
||||
-moz-box-align: center;
|
||||
}
|
||||
|
||||
#zotero-attachment-index-box > button
|
||||
{
|
||||
font-size: .95em;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
||||
#zotero-splitter
|
||||
{
|
||||
border-top: none;
|
||||
|
|
|
@ -3,6 +3,16 @@ prefwindow .chromeclass-toolbar
|
|||
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]
|
||||
{
|
||||
min-width: 5.5em;
|
||||
|
@ -11,46 +21,64 @@ radio[pane]
|
|||
-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]
|
||||
{
|
||||
list-style-image: url("chrome://zotero/skin/prefs-general.png");
|
||||
}
|
||||
|
||||
/*
|
||||
* Export pane icon
|
||||
*/
|
||||
radio[pane=zotero-prefpane-export]
|
||||
grid row:not(:first-child)
|
||||
{
|
||||
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
|
||||
{
|
||||
-moz-box-pack: end;
|
||||
-moz-box-pack: end; /* Right-justify left column */
|
||||
}
|
||||
|
||||
#position-menu-box-label, #position-menu-box
|
||||
{
|
||||
-moz-box-align: center;
|
||||
}
|
||||
|
||||
#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 */
|
||||
radio[pane=zotero-prefpane-export]
|
||||
{
|
||||
list-style-image: url("chrome://zotero/skin/prefs-export.png");
|
||||
}
|
||||
|
||||
#quickCopy-instructions, #zotero-prefpane-export vbox {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
@ -119,6 +191,11 @@ grid row hbox:first-child
|
|||
|
||||
|
||||
/* Shortcut Keys pane */
|
||||
radio[pane=zotero-prefpane-keys]
|
||||
{
|
||||
list-style-image: url("chrome://zotero/skin/prefs-keys.png");
|
||||
}
|
||||
|
||||
#zotero-prefpane-keys row
|
||||
{
|
||||
-moz-box-align: center;
|
||||
|
@ -139,3 +216,12 @@ grid row hbox:first-child
|
|||
margin: .75em 0;
|
||||
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
|
||||
-- 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)
|
||||
);
|
||||
|
||||
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 (
|
||||
wordID INTEGER PRIMARY KEY,
|
||||
word TEXT UNIQUE
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS fulltextWords_word ON fulltextWords(word);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS fulltextItems (
|
||||
CREATE TABLE IF NOT EXISTS fulltextItemWords (
|
||||
wordID 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 (
|
||||
translatorID TEXT PRIMARY KEY,
|
||||
|
|
Loading…
Reference in New Issue
Block a user