www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | Submodules | README | LICENSE

commit e30890711ad29c45d9f6e670151318f014dcd1d9
parent ce67b52ed48ce6b7c530bc2069e3572fdc3ee1b6
Author: Simon Kornblith <simon@simonster.com>
Date:   Fri, 11 Feb 2011 08:07:20 +0000

- locate menu tweaks (needs more testing)
- add missing modifications for DB error when selecting tab in Fx 4


Diffstat:
Mchrome/content/zotero/locateMenu.js | 471++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
Mchrome/content/zotero/tab.js | 4++++
Mchrome/content/zotero/xpcom/data/item.js | 18++++++++++++++++--
Mchrome/content/zotero/zoteroPane.js | 30++++++++++++++++--------------
Mchrome/content/zotero/zoteroPane.xul | 2+-
Mchrome/locale/en-US/zotero/zotero.properties | 17+++++++++++------
Achrome/skin/default/zotero/locate-external-viewer.png | 0
Achrome/skin/default/zotero/locate-internal-viewer.png | 0
Achrome/skin/default/zotero/locate-library-lookup.png | 0
Achrome/skin/default/zotero/locate-show-file.png | 0
Achrome/skin/default/zotero/locate-view-online.png | 0
11 files changed, 356 insertions(+), 186 deletions(-)

diff --git a/chrome/content/zotero/locateMenu.js b/chrome/content/zotero/locateMenu.js @@ -31,105 +31,6 @@ Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); var Zotero_LocateMenu = new function() { XPCOMUtils.defineLazyServiceGetter(this, "ios", "@mozilla.org/network/io-service;1", "nsIIOService"); - /** - * Create a new menuitem XUL element - */ - function _createMenuItem( label, id, tooltiptext ) { - var menuitem = document.createElement("menuitem"); - menuitem.setAttribute("label", label); - if(id) menuitem.setAttribute("id", id); - if(tooltiptext) menuitem.setAttribute("tooltiptext", tooltiptext); - - return menuitem; - } - - /** - * Get snapshot IDs for items - */ - function _getSnapshotIDs(items) { - var ids = []; - for each(var item in items) { - if(item.isNote()) continue; - var snapID = (item.isAttachment() ? item.id : item.getBestAttachment()); - if(!snapID) continue; - var spec = Zotero.Items.get(snapID).getLocalFileURL(); - if(!spec) continue; - var uri = Zotero_LocateMenu.ios.newURI(spec, null, null); - if(!uri || uri.scheme != 'file') continue; - ids.push(snapID); - } - return ids; - } - - /** - * Get URLs for items - */ - function _getURLs(items, includeDOIs) { - var urls = []; - for each(var item in items) { - if(item.isNote()) continue; - var url = null; - - // try url field - var urlField = item.getField('url'); - if(urlField) { - var uri = Zotero_LocateMenu.ios.newURI(urlField, null, null); - if(uri && (uri.host || !uri.scheme !== 'file')) { - url = urlField; - } - } - - if(includeDOIs) { - if(!url) { - // try DOI field - var doi = item.getField('DOI'); - if(doi && typeof doi === "string") { - doi = Zotero.Utilities.cleanDOI(doi); - if(doi) url = "http://dx.doi.org/" + encodeURIComponent(doi); - } - } - } - - if(url) urls.push(url); - } - return urls; - } - - /** - * Get any locate engines that can be installed from the current page - */ - function _getInstallableLocateEngines() { - var locateEngines = []; - if(!window.Zotero_Browser || !window.Zotero_Browser.tabbrowser) return locateEngines; - - var links = Zotero_Browser.tabbrowser.selectedBrowser.contentDocument.getElementsByTagName("link"); - for each(var link in links) { - if(!link.getAttribute) continue; - var rel = link.getAttribute("rel"); - if(rel && rel === "search") { - var type = link.getAttribute("type"); - if(type && type === "application/x-openurl-opensearchdescription+xml") { - var label = link.getAttribute("title"); - if(label) { - if(Zotero.LocateManager.getEngineByName(label)) { - label = 'Update "'+label+'"'; - } else { - label = 'Add "'+label+'"'; - } - } else { - label = 'Add Locate Engine'; - } - - locateEngines.push({'label':label, - 'href':link.getAttribute("href"), - 'image':Zotero_Browser.tabbrowser.selectedTab.image}); - } - } - } - - return locateEngines; - } - /** * Clear and build the locate menu */ @@ -144,43 +45,36 @@ var Zotero_LocateMenu = new function() { var selectedItems = [item for each(item in ZoteroPane.getSelectedItems()) if(!item.isNote())]; if(selectedItems.length) { - // get snapshot IDs and URLs - var allURLs = _getURLs(selectedItems, true); - var realURLs = _getURLs(selectedItems); - - if(selectedItems.length == 1 && _getSnapshotIDs(selectedItems).length) { - // add view snapshot - var menuitem = _createMenuItem(Zotero.getString("locate.snapshot.label"), - "zotero-locate-snapshot", Zotero.getString("locate.snapshot.tooltip")); - locateMenu.appendChild(menuitem); - menuitem.addEventListener("command", this.openItemSnapshot, false); - } - - if(allURLs.length) { - // add view online - var menuitem = _createMenuItem(Zotero.getString("locate.online.label"), - "zotero-locate-online", Zotero.getString("locate.online.tooltip")); - locateMenu.appendChild(menuitem); - menuitem.addEventListener("command", this.openItemURL, false); - } + var optionsToShow = {}; - // add library lookup to regular items - var regularItems = [item for each(item in selectedItems) if(item.isRegularItem())]; - if(regularItems.length) { - var menuitem = _createMenuItem(Zotero.getString("locate.libraryLookup.label"), - "zotero-locate-service-openurl", Zotero.getString("locate.libraryLookup.tooltip")); - locateMenu.appendChild(menuitem); - menuitem.addEventListener("command", this.lookupItem, false); + // check which view options are available + for each(var item in selectedItems) { + for(var viewOption in ViewOptions) { + if(!optionsToShow[viewOption]) { + Zotero.debug("testing "+viewOption); + optionsToShow[viewOption] = ViewOptions[viewOption].canHandleItem(item); + } + } } - // add wayback if there are real URLs - if(realURLs.length) { - var menuitem = _createMenuItem(Zotero.getString("locate.waybackMachine.label"), - "zotero-locate-service-wayback", Zotero.getString("locate.waybackMachine.tooltip")); + // add available view options to menu + for(var viewOption in optionsToShow) { + if(!optionsToShow[viewOption]) continue; + + var menuitem = _createMenuItem(Zotero.getString("locate."+viewOption+".label"), + null, Zotero.getString("locate."+viewOption+".tooltip")); + menuitem.setAttribute("class", "menuitem-iconic"); + Zotero.debug("icon is "+ViewOptions[viewOption].icon); + menuitem.setAttribute("image", ViewOptions[viewOption].icon); locateMenu.appendChild(menuitem); - menuitem.addEventListener("command", this.waybackItem, false); + + let myViewOption = viewOption; + menuitem.addEventListener("command", function(event) { + ViewOptions[myViewOption].handleItems(selectedItems, event); + }, false) } + // check for custom locate engines var customEngines = Zotero.LocateManager.getVisibleEngines(); if(customEngines.length) { locateMenu.appendChild(document.createElement("menuseparator")); @@ -201,7 +95,7 @@ var Zotero_LocateMenu = new function() { menuitem.setAttribute("class", "menuitem-iconic"); menuitem.setAttribute("image", engine.icon); locateMenu.appendChild(menuitem); - menuitem.addEventListener("command", this.locateItem, false); + menuitem.addEventListener("command", _locateItem, false); } } } @@ -225,9 +119,10 @@ var Zotero_LocateMenu = new function() { for each(var locateEngine in installableLocateEngines) { var menuitem = document.createElement("menuitem"); menuitem.setAttribute("label", locateEngine.label); + menuitem.setAttribute("class", "menuitem-iconic"); menuitem.setAttribute("image", locateEngine.image); menuitem.zoteroLocateInfo = locateEngine; - menuitem.addEventListener("command", this.addLocateEngine, false); + menuitem.addEventListener("command", _addLocateEngine, false); locateMenu.appendChild(menuitem); } @@ -238,49 +133,61 @@ var Zotero_LocateMenu = new function() { var menuitem = document.createElement("menuitem"); menuitem = _createMenuItem(Zotero.getString("locate.manageLocateEngines"), "zotero-manage-locate-menu"); - menuitem.addEventListener("command", this.openLocateEngineManager, false); + menuitem.addEventListener("command", _openLocateEngineManager, false); locateMenu.appendChild(menuitem); } /** - * Open snapshots for selected items - */ - this.openItemSnapshot = function(event) { - ZoteroPane.viewAttachment(_getSnapshotIDs(ZoteroPane.getSelectedItems())[0], event); - } - - /** - * Open URLs for selected items + * Create a new menuitem XUL element */ - this.openItemURL = function(event) { - ZoteroPane.loadURI(_getURLs(ZoteroPane.getSelectedItems(), true), event); + function _createMenuItem( label, id, tooltiptext ) { + var menuitem = document.createElement("menuitem"); + menuitem.setAttribute("label", label); + if(id) menuitem.setAttribute("id", id); + if(tooltiptext) menuitem.setAttribute("tooltiptext", tooltiptext); + + return menuitem; } /** - * Perform library lookup of selected items + * Get any locate engines that can be installed from the current page */ - this.lookupItem = function(event) { - var urls = []; - for each(var item in ZoteroPane.getSelectedItems()) { - if(!item.isRegularItem()) continue; - var url = Zotero.OpenURL.resolve(item); - if(url) urls.push(url); + function _getInstallableLocateEngines() { + var locateEngines = []; + if(!window.Zotero_Browser || !window.Zotero_Browser.tabbrowser) return locateEngines; + + var links = Zotero_Browser.tabbrowser.selectedBrowser.contentDocument.getElementsByTagName("link"); + for each(var link in links) { + if(!link.getAttribute) continue; + var rel = link.getAttribute("rel"); + if(rel && rel === "search") { + var type = link.getAttribute("type"); + if(type && type === "application/x-openurl-opensearchdescription+xml") { + var label = link.getAttribute("title"); + if(label) { + if(Zotero.LocateManager.getEngineByName(label)) { + label = 'Update "'+label+'"'; + } else { + label = 'Add "'+label+'"'; + } + } else { + label = 'Add Locate Engine'; + } + + locateEngines.push({'label':label, + 'href':link.getAttribute("href"), + 'image':Zotero_Browser.tabbrowser.selectedTab.image}); + } + } } - ZoteroPane.loadURI(urls, event); - } - - /** - * Perform library lookup of selected items - */ - this.waybackItem = function(event) { - ZoteroPane.loadURI(["http://web.archive.org/web/*/"+url - for each(url in _getURLs(ZoteroPane.getSelectedItems()))], event); + + return locateEngines; } /** * Locate selected items */ - this.locateItem = function(event) { + function _locateItem(event) { var selectedItems = ZoteroPane.getSelectedItems(); // find selected engine @@ -303,7 +210,7 @@ var Zotero_LocateMenu = new function() { /** * Add a new locate engine */ - this.addLocateEngine = function(event) { + function _addLocateEngine(event) { Zotero.LocateManager.addEngine(event.target.zoteroLocateInfo.href, Components.interfaces.nsISearchEngine.TYPE_OPENSEARCH, event.target.zoteroLocateInfo.image, false); @@ -312,10 +219,247 @@ var Zotero_LocateMenu = new function() { /** * Open the locate manager */ - this.openLocateEngineManager = function(event) { + function _openLocateEngineManager(event) { window.openDialog('chrome://zotero/content/locateManager.xul', 'Zotero Locate Engine Manager', 'chrome,centerscreen' ); } -} + + var ViewOptions = {}; + + /** + * "View Online" option + * + * Should appear only when an item or an attachment has a URL + */ + ViewOptions.online = new function() { + this.icon = "chrome://zotero/skin/locate-view-online.png"; + this.canHandleItem = function(item) _getURL(item) !== false; + + this.handleItems = function(items, event) { + ZoteroPane.loadURI([_getURL(item) for each(item in items)], event); + } + + function _getURL(item) { + // try url field for item and for attachments + var urlFields = [item.getField('url')]; + if(item.isRegularItem()) { + var attachments = item.getAttachments(); + if(attachments) { + urlFields = urlFields.concat([attachment.getField('url') + for each(attachment in Zotero.Items.get(attachments))]); + } + } + + // look through url fields for non-file:/// attachments + for each(var urlField in urlFields) { + try { + Zotero.debug(urlField); + var uri = Zotero_LocateMenu.ios.newURI(urlField, null, null); + if(uri && uri.host && uri.scheme !== 'file') { + return urlField; + } + } catch(e) {}; + } + + // if no url field, try DOI field + var doi = item.getField('DOI'); + if(doi && typeof doi === "string") { + doi = Zotero.Utilities.cleanDOI(doi); + if(doi) { + return "http://dx.doi.org/" + encodeURIComponent(doi); + } + } + + return false; + } + }; + + /** + * "View PDF" option + * + * Should appear only when the item is a PDF, or a linked or attached file or web attachment is + * a PDF + */ + ViewOptions.pdf = new function() { + this.icon = "chrome://zotero/skin/treeitem-attachment-pdf.png"; + this._mimeTypes = ["application/pdf"]; + this.canHandleItem = function(item) !!_getFirstAttachmentWithMIMEType(item, this._mimeTypes); + + this.handleItems = function(items, event) { + for each(var item in items) { + var attachment = _getFirstAttachmentWithMIMEType(item, this._mimeTypes); + if(attachment) { + ZoteroPane.viewAttachment(attachment.id, event); + return; + } + } + } + + function _getFirstAttachmentWithMIMEType(item, mimeTypes) { + var attachments = (item.isAttachment() ? [item] : Zotero.Items.get(item.getBestAttachments())); + for each(var attachment in attachments) { + if(mimeTypes.indexOf(attachment.attachmentMIMEType) !== -1 + && item.linkMode != Zotero.Attachments.LINK_MODE_LINKED_URL) return attachment; + } + return false; + } + }; + + /** + * "View Snapshot" option + * + * Should appear only when the item is a PDF, or a linked or attached file or web attachment is + * a snapshot + */ + ViewOptions.snapshot = new function() { + this.icon = "chrome://zotero/skin/treeitem-attachment-snapshot.png"; + this._mimeTypes = ["text/html", "application/xhtml+xml"]; + this.canHandleItem = ViewOptions.pdf.canHandleItem; + this.handleItems = ViewOptions.pdf.handleItems; + }; + + /** + * "View File" option + * + * Should appear only when an item or a linked or attached file or web attachment does not + * satisfy the conditions for "View PDF" or "View Snapshot" + */ + ViewOptions.file = new function() { + this.icon = "chrome://zotero/skin/treeitem-attachment-file.png"; + this.canHandleItem = function(item) !!_getFile(item); + + this.handleItems = function(items, event) { + for each(var item in items) { + var attachment = _getFile(item); + if(attachment) { + ZoteroPane.viewAttachment(attachment.id, event); + return; + } + } + } + + function _getFile(item) { + var attachments = (item.isAttachment() ? [item] : Zotero.Items.get(item.getBestAttachments())); + for each(var attachment in attachments) { + if(!ViewOptions.snapshot.canHandleItem(attachment) + && !ViewOptions.pdf.canHandleItem(attachment) + && item.linkMode != Zotero.Attachments.LINK_MODE_LINKED_URL) { + return attachment; + } + } + return false; + } + }; + + /** + * "Open in External Viewer" option + * + * Should appear only when an item or a linked or attached file or web attachment can be + * viewed by an internal non-native handler and "launchNonNativeFiles" pref is disabled + */ + ViewOptions.externalViewer = new function() { + this.icon = "chrome://zotero/skin/locate-external-viewer.png"; + this.useExternalViewer = true; + + this.canHandleItem = function(item) { + return (this.useExternalViewer ^ Zotero.Prefs.get('launchNonNativeFiles')) + && _getBestNonNativeAttachment(item); + } + + this.handleItems = function(items, event) { + for each(var item in items) { + var attachment = _getBestNonNativeAttachment(item); + if(attachment) { + ZoteroPane.viewAttachment(attachment.id, event, false, this.useExternalViewer); + return; + } + } + } + + function _getBestNonNativeAttachment(item) { + var attachments = (item.isAttachment() ? [item] : Zotero.Items.get(item.getBestAttachments())); + for each(var attachment in attachments) { + if(attachment.linkMode != Zotero.Attachments.LINK_MODE_LINKED_URL) { + var file = attachment.getFile(); + if(file) { + var ext = Zotero.File.getExtension(file); + if(!attachment.attachmentMIMEType) continue; + if(!Zotero.MIME.hasNativeHandler(attachment.attachmentMIMEType, ext) && + Zotero.MIME.hasInternalHandler(attachment.attachmentMIMEType, ext)) { + return attachment; + } + } + } + } + return false; + } + }; + + /** + * "Open in Internal Viewer" option + * + * Should appear only when an item or a linked or attached file or web attachment can be + * viewed by an internal non-native handler and "launchNonNativeFiles" pref is enabled + */ + ViewOptions.internalViewer = new function() { + this.icon = "chrome://zotero/skin/locate-internal-viewer.png"; + this.useExternalViewer = false; + this.canHandleItem = ViewOptions.externalViewer.canHandleItem; + this.handleItems = ViewOptions.externalViewer.handleItems; + }; + + /** + * "Show File" option + * + * Should appear only when an item is a file or web attachment, or has a linked or attached + * file or web attachment + */ + ViewOptions.showFile = new function() { + this.icon = "chrome://zotero/skin/locate-show-file.png"; + this.useExternalViewer = true; + + this.canHandleItem = function(item) { + return !!_getBestFile(item); + } + + this.handleItems = function(items, event) { + for each(var item in items) { + var attachment = _getBestFile(item); + if(attachment) { + ZoteroPane.showAttachmentInFilesystem(attachment.id); + return; + } + } + } + + function _getBestFile(item) { + if(item.isAttachment()) { + if(item.linkMode === Zotero.Attachments.LINK_MODE_LINKED_URL) return false + return item; + } else { + return Zotero.Items.get(item.getBestAttachment()); + } + } + }; + + /** + * "Library Lookup" Option + * + * Should appear only for regular items + */ + ViewOptions.libraryLookup = new function() { + this.icon = "chrome://zotero/skin/locate-library-lookup.png"; + this.canHandleItem = function(item) item.isRegularItem(); + this.handleItems = function(items, event) { + var urls = []; + for each(var item in items) { + if(!item.isRegularItem()) continue; + var url = Zotero.OpenURL.resolve(item); + if(url) urls.push(url); + } + ZoteroPane.loadURI(urls, event); + } + }; +} +\ No newline at end of file diff --git a/chrome/content/zotero/tab.js b/chrome/content/zotero/tab.js @@ -81,6 +81,10 @@ var ZoteroTab = new function() var listener = function(event) { if(event.target !== tab) return; window.gBrowser.tabContainer.removeEventListener("TabSelect", listener, false); + if(!Zotero || !Zotero.initialized) { + ZoteroPane.displayStartupError(true); + return; + } ZoteroPane.init(); ZoteroPane.makeVisible(); } diff --git a/chrome/content/zotero/xpcom/data/item.js b/chrome/content/zotero/xpcom/data/item.js @@ -3195,7 +3195,7 @@ Zotero.Item.prototype.getAttachments = function(includeTrashed) { if (!this.id) { return []; } - + var sql = "SELECT A.itemID, value AS title FROM itemAttachments A " + "NATURAL JOIN items I LEFT JOIN itemData ID " + "ON (fieldID=110 AND A.itemID=ID.itemID) " @@ -3250,6 +3250,20 @@ Zotero.Item.prototype.getBestAttachment = function() { if (!this.isRegularItem()) { throw ("getBestAttachment() can only be called on regular items"); } + return this.getBestAttachments()[0]; +} + +/* + * Looks for attachment in the following order: oldest PDF attachment matching parent URL, + * oldest non-PDF attachment matching parent URL, oldest PDF attachment not matching URL, + * old non-PDF attachment not matching URL + * + * @return {Array} itemIDs for attachments + */ +Zotero.Item.prototype.getBestAttachments = function() { + if (!this.isRegularItem()) { + throw ("getBestAttachments() can only be called on regular items"); + } var url = this.getField('url'); @@ -3259,7 +3273,7 @@ Zotero.Item.prototype.getBestAttachment = function() { + "WHERE sourceItemID=? AND linkMode NOT IN (?) " + "AND IA.itemID NOT IN (SELECT itemID FROM deletedItems) " + "ORDER BY value=? DESC, mimeType='application/pdf' DESC, dateAdded ASC"; - return Zotero.DB.valueQuery(sql, [this.id, Zotero.Attachments.LINK_MODE_LINKED_URL, url]); + return Zotero.DB.columnQuery(sql, [this.id, Zotero.Attachments.LINK_MODE_LINKED_URL, url]); } diff --git a/chrome/content/zotero/zoteroPane.js b/chrome/content/zotero/zoteroPane.js @@ -3029,7 +3029,7 @@ var ZoteroPane = new function() } - function viewAttachment(itemID, event, noLocateOnMissing) { + function viewAttachment(itemID, event, noLocateOnMissing, forceExternalViewer) { var attachment = Zotero.Items.get(itemID); if (!attachment.isAttachment()) { throw ("Item " + itemID + " is not an attachment in ZoteroPane.viewAttachment()"); @@ -3042,22 +3042,24 @@ var ZoteroPane = new function() var file = attachment.getFile(); if (file) { - var mimeType = attachment.getAttachmentMIMEType(); - // If no MIME type specified, try to detect again (I guess in case - // we've gotten smarter since the file was imported?) - if (!mimeType) { - var mimeType = Zotero.MIME.getMIMETypeFromFile(file); - var ext = Zotero.File.getExtension(file); + if(forceExternalViewer !== undefined) { + var externalViewer = forceExternalViewer; + } else { + var mimeType = attachment.getAttachmentMIMEType(); + // If no MIME type specified, try to detect again (I guess in case + // we've gotten smarter since the file was imported?) + if (!mimeType) { + mimeType = Zotero.MIME.getMIMETypeFromFile(file); + + // TODO: update DB with new info + } - // TODO: update DB with new info + var ext = Zotero.File.getExtension(file); + var externalViewer = Zotero.isStandalone || (!Zotero.MIME.hasNativeHandler(mimeType, ext) && + (!Zotero.MIME.hasInternalHandler(mimeType, ext) || Zotero.Prefs.get('launchNonNativeFiles'))); } - var ext = Zotero.File.getExtension(file); - var isNative = Zotero.MIME.hasNativeHandler(mimeType, ext); - var internal = Zotero.MIME.hasInternalHandler(mimeType, ext); - if (isNative || - (internal && !Zotero.Prefs.get('launchNonNativeFiles'))) { - + if (!forceExternalViewer) { var url = 'zotero://attachment/' + itemID + '/'; this.loadURI(url, event, { attachmentID: itemID}); } diff --git a/chrome/content/zotero/zoteroPane.xul b/chrome/content/zotero/zoteroPane.xul @@ -43,7 +43,7 @@ <script src="timelineInterface.js"/> <script src="recognizePDF.js"/> <script src="browser.js"/> - <script src="locateMenu.js"/> + <script src="locateMenu.js" type="application/javascript;version=1.7"/> <commandset id="mainCommandSet"> <command id="cmd_zotero_search" oncommand="ZoteroPane.search();"/> diff --git a/chrome/locale/en-US/zotero/zotero.properties b/chrome/locale/en-US/zotero/zotero.properties @@ -182,9 +182,6 @@ pane.item.notes.count.plural = %S notes: pane.item.attachments.rename.title = New title: pane.item.attachments.rename.renameAssociatedFile = Rename associated file pane.item.attachments.rename.error = An error occurred while renaming the file. -pane.item.attachments.view.link = View Page -pane.item.attachments.view.snapshot = View Snapshot -pane.item.attachments.view.file = View File pane.item.attachments.fileNotFound.title = File Not Found pane.item.attachments.fileNotFound.text = The attached file could not be found.\n\nIt may have been moved or deleted outside of Zotero. pane.item.attachments.delete.confirm = Are you sure you want to delete this attachment? @@ -709,10 +706,18 @@ lookup.failure.description = Zotero could not find a record for the specified locate.online.label = View Online locate.online.tooltip = Go to this item online +locate.pdf.label = View PDF +locate.pdf.tooltip = Open PDF using the selected viewer locate.snapshot.label = View Snapshot -locate.snapshot.tooltip = View snapshot for this item +locate.snapshot.tooltip = View and annotate the snapshot for this item +locate.file.label = View File +locate.file.tooltip = Open file using the selected viewer +locate.externalViewer.label = Open in External Viewer +locate.externalViewer.tooltip = Open file in another application +locate.internalViewer.label = Open in Internal Viewer +locate.internalViewer.tooltip = Open file in this application +locate.showFile.label = Show File +locate.showFile.tooltip = Open the directory in which this file resides locate.libraryLookup.label = Library Lookup locate.libraryLookup.tooltip = Look up this item using the selected OpenURL resolver -locate.waybackMachine.label = Wayback Machine -locate.waybackMachine.tooltip = View an archived version of this item locate.manageLocateEngines = Manage Locate Engines... \ No newline at end of file diff --git a/chrome/skin/default/zotero/locate-external-viewer.png b/chrome/skin/default/zotero/locate-external-viewer.png Binary files differ. diff --git a/chrome/skin/default/zotero/locate-internal-viewer.png b/chrome/skin/default/zotero/locate-internal-viewer.png Binary files differ. diff --git a/chrome/skin/default/zotero/locate-library-lookup.png b/chrome/skin/default/zotero/locate-library-lookup.png Binary files differ. diff --git a/chrome/skin/default/zotero/locate-show-file.png b/chrome/skin/default/zotero/locate-show-file.png Binary files differ. diff --git a/chrome/skin/default/zotero/locate-view-online.png b/chrome/skin/default/zotero/locate-view-online.png Binary files differ.