- Abstract attachment info pane into XBL binding
- Add attachment conflict resolution
This commit is contained in:
parent
403663664c
commit
8ad23d7eea
430
chrome/content/zotero/bindings/attachmentbox.xml
Normal file
430
chrome/content/zotero/bindings/attachmentbox.xml
Normal file
|
@ -0,0 +1,430 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!--
|
||||||
|
***** BEGIN LICENSE BLOCK *****
|
||||||
|
|
||||||
|
Copyright (c) 2006 Center for History and New Media
|
||||||
|
George Mason University, Fairfax, Virginia, USA
|
||||||
|
http://chnm.gmu.edu
|
||||||
|
|
||||||
|
Licensed under the Educational Community License, Version 1.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.opensource.org/licenses/ecl1.php
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
***** END LICENSE BLOCK *****
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!DOCTYPE bindings SYSTEM "chrome://zotero/locale/zotero.dtd">
|
||||||
|
<!-- <!DOCTYPE bindings SYSTEM "chrome://zotero/locale/attachmentbox.dtd"> -->
|
||||||
|
|
||||||
|
<bindings xmlns="http://www.mozilla.org/xbl"
|
||||||
|
xmlns:xbl="http://www.mozilla.org/xbl"
|
||||||
|
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||||
|
|
||||||
|
<binding id="attachment-box">
|
||||||
|
<resources>
|
||||||
|
<stylesheet src="chrome://zotero/skin/bindings/attachmentbox.css"/>
|
||||||
|
</resources>
|
||||||
|
|
||||||
|
<implementation>
|
||||||
|
<!--
|
||||||
|
Public properties
|
||||||
|
-->
|
||||||
|
<field name="editable">false</field>
|
||||||
|
<field name="displayGoButtons">false</field>
|
||||||
|
<field name="clickableLink">false</field>
|
||||||
|
<field name="displayButton">false</field>
|
||||||
|
|
||||||
|
<field name="buttonCaption"/>
|
||||||
|
<field name="clickHandler"/>
|
||||||
|
|
||||||
|
<!-- Modes are predefined settings groups for particular tasks -->
|
||||||
|
<field name="_mode">"view"</field>
|
||||||
|
<property name="mode" onget="return this._mode;">
|
||||||
|
<setter>
|
||||||
|
<![CDATA[
|
||||||
|
this.editable = false;
|
||||||
|
this.displayGoButtons = false;
|
||||||
|
this.clickableLink = false;
|
||||||
|
this.displayIndexed = false;
|
||||||
|
this.displayPages = false;
|
||||||
|
|
||||||
|
switch (val) {
|
||||||
|
case 'view':
|
||||||
|
this.displayGoButtons = true;
|
||||||
|
this.clickableLink = true;
|
||||||
|
this.displayIndexed = true;
|
||||||
|
this.displayPages = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'edit':
|
||||||
|
this.editable = true;
|
||||||
|
this.displayGoButtons = true;
|
||||||
|
this.clickableLink = true;
|
||||||
|
this.displayIndexed = true;
|
||||||
|
this.displayPages = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'merge':
|
||||||
|
this.displayButton = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'mergeedit':
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw ("Invalid mode '" + val + "' in attachmentbox.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
this._mode = val;
|
||||||
|
document.getAnonymousNodes(this)[0].setAttribute('mode', val);
|
||||||
|
]]>
|
||||||
|
</setter>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<field name="_item"/>
|
||||||
|
<property name="item"
|
||||||
|
onget="return this._item;"
|
||||||
|
onset="this._item = val; this.refresh();">
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<!-- .ref is an alias for .item -->
|
||||||
|
<property name="ref"
|
||||||
|
onget="return this._item;"
|
||||||
|
onset="this._item = val; this.refresh();">
|
||||||
|
</property>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Private properties -->
|
||||||
|
|
||||||
|
<method name="refresh">
|
||||||
|
<body>
|
||||||
|
<![CDATA[
|
||||||
|
Zotero.debug('Refreshing attachment box');
|
||||||
|
|
||||||
|
var attachmentBox = document.getAnonymousNodes(this)[0];
|
||||||
|
var title = this._id('title');
|
||||||
|
var goButtons = this._id('go-buttons');
|
||||||
|
var viewButton = this._id('view');
|
||||||
|
var showButton = this._id('show');
|
||||||
|
var urlField = this._id('url');
|
||||||
|
var accessed = this._id('accessed');
|
||||||
|
var pagesRow = this._id('pages');
|
||||||
|
var indexBox = this._id('index-box');
|
||||||
|
var selectButton = this._id('select-button');
|
||||||
|
|
||||||
|
// DEBUG: this is annoying -- we really want to use an abstracted
|
||||||
|
// version of createValueElement() from itemPane.js
|
||||||
|
// (ideally in an XBL binding)
|
||||||
|
|
||||||
|
// Wrap title to multiple lines if necessary
|
||||||
|
while (title.hasChildNodes()) {
|
||||||
|
title.removeChild(title.firstChild);
|
||||||
|
}
|
||||||
|
var val = this.item.getField('title');
|
||||||
|
|
||||||
|
var firstSpace = val.indexOf(" ");
|
||||||
|
// Crop long uninterrupted text
|
||||||
|
if ((firstSpace == -1 && val.length > 29 ) || firstSpace > 29) {
|
||||||
|
title.setAttribute('crop', 'end');
|
||||||
|
title.setAttribute('value', val);
|
||||||
|
}
|
||||||
|
// Create a <description> element, essentially
|
||||||
|
else {
|
||||||
|
title.removeAttribute('value');
|
||||||
|
title.appendChild(document.createTextNode(val));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.editable) {
|
||||||
|
title.className = 'zotero-clicky';
|
||||||
|
|
||||||
|
// For the time being, use a silly little popup
|
||||||
|
title.addEventListener('click', this.editTitle, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// View and Show buttons
|
||||||
|
if (this.displayGoButtons) {
|
||||||
|
goButtons.hidden = false;
|
||||||
|
|
||||||
|
var itemID = this.item.id;
|
||||||
|
var noLocateOnMissing = !this.editable;
|
||||||
|
viewButton.onclick = function (event) {
|
||||||
|
ZoteroPane.viewAttachment(itemID, event, noLocateOnMissing)
|
||||||
|
}
|
||||||
|
showButton.onclick = function (event) {
|
||||||
|
ZoteroPane.showAttachmentInFilesystem(itemID, noLocateOnMissing)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
goButtons.hidden = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var isImportedURL = this.item.attachmentLinkMode ==
|
||||||
|
Zotero.Attachments.LINK_MODE_IMPORTED_URL;
|
||||||
|
|
||||||
|
// Metadata for URL's
|
||||||
|
if (this.item.attachmentLinkMode == Zotero.Attachments.LINK_MODE_LINKED_URL
|
||||||
|
|| isImportedURL) {
|
||||||
|
// "View Page"/"View Snapshot" label
|
||||||
|
if (isImportedURL) {
|
||||||
|
var str = Zotero.getString('pane.item.attachments.view.snapshot');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var str = Zotero.getString('pane.item.attachments.view.link');
|
||||||
|
}
|
||||||
|
|
||||||
|
showButton.setAttribute('hidden', !isImportedURL);
|
||||||
|
|
||||||
|
// URL
|
||||||
|
var urlSpec = this.item.getField('url');
|
||||||
|
urlField.setAttribute('value', urlSpec);
|
||||||
|
urlField.setAttribute('hidden', false);
|
||||||
|
if (this.clickableLink) {
|
||||||
|
urlField.onclick = function (event) {
|
||||||
|
ZoteroPane.loadURI(this.value, event)
|
||||||
|
};
|
||||||
|
urlField.className = 'text-link';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
urlField.className = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Access date
|
||||||
|
accessed.setAttribute('value',
|
||||||
|
Zotero.getString('itemFields.accessDate') + ': '
|
||||||
|
+ Zotero.Date.sqlToDate(this.item.getField('accessDate'), true).toLocaleString());
|
||||||
|
accessed.setAttribute('hidden', false);
|
||||||
|
}
|
||||||
|
// Metadata for files
|
||||||
|
else {
|
||||||
|
var str = Zotero.getString('pane.item.attachments.view.file');
|
||||||
|
showButton.setAttribute('hidden', false);
|
||||||
|
urlField.setAttribute('hidden', true);
|
||||||
|
accessed.setAttribute('hidden', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
viewButton.setAttribute('label', str);
|
||||||
|
|
||||||
|
// Page count
|
||||||
|
if (this.displayPages) {
|
||||||
|
var pages = Zotero.Fulltext.getPages(this.item.id);
|
||||||
|
var pages = pages ? pages.total : null;
|
||||||
|
if (pages) {
|
||||||
|
var str = Zotero.getString('itemFields.pages') + ': ' + pages;
|
||||||
|
pagesRow.setAttribute('value', str);
|
||||||
|
pagesRow.setAttribute('hidden', false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pagesRow.setAttribute('hidden', true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pagesRow.setAttribute('hidden', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Full-text index information
|
||||||
|
if (this.displayIndexed) {
|
||||||
|
this.updateItemIndexedState();
|
||||||
|
indexBox.hidden = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
indexBox.hidden = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note editor
|
||||||
|
var noteEditor = this._id('note-editor');
|
||||||
|
// Don't make note editable (at least for now)
|
||||||
|
if (this.mode == 'merge' || this.mode == 'mergeedit') {
|
||||||
|
noteEditor.mode = 'merge';
|
||||||
|
noteEditor.displayButton = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
noteEditor.mode = this.mode;
|
||||||
|
}
|
||||||
|
noteEditor.parent = null;
|
||||||
|
noteEditor.item = this.item;
|
||||||
|
|
||||||
|
if (this.displayButton) {
|
||||||
|
selectButton.label = this.buttonCaption;
|
||||||
|
selectButton.hidden = false;
|
||||||
|
selectButton.setAttribute('oncommand',
|
||||||
|
'document.getBindingParent(this).clickHandler(this)');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
selectButton.hidden = true;
|
||||||
|
}
|
||||||
|
]]>
|
||||||
|
</body>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
|
||||||
|
<method name="editTitle">
|
||||||
|
<body>
|
||||||
|
<![CDATA[
|
||||||
|
var item = document.getBindingParent(this).item;
|
||||||
|
var oldTitle = item.getField('title');
|
||||||
|
|
||||||
|
var nsIPS = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
|
||||||
|
.getService(Components.interfaces.nsIPromptService);
|
||||||
|
|
||||||
|
var newTitle = { value: oldTitle };
|
||||||
|
var checkState = { value: Zotero.Prefs.get('lastRenameAssociatedFile') };
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
// Don't show "Rename associated file" option for
|
||||||
|
// linked URLs
|
||||||
|
if (item.attachmentLinkMode ==
|
||||||
|
Zotero.Attachments.LINK_MODE_LINKED_URL) {
|
||||||
|
var result = nsIPS.prompt(
|
||||||
|
window,
|
||||||
|
'',
|
||||||
|
Zotero.getString('pane.item.attachments.rename.title'),
|
||||||
|
newTitle,
|
||||||
|
null,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
|
||||||
|
// If they hit cancel or left it blank
|
||||||
|
if (!result || !newTitle.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = nsIPS.prompt(
|
||||||
|
window,
|
||||||
|
'',
|
||||||
|
Zotero.getString('pane.item.attachments.rename.title'),
|
||||||
|
newTitle,
|
||||||
|
Zotero.getString('pane.item.attachments.rename.renameAssociatedFile'),
|
||||||
|
checkState
|
||||||
|
);
|
||||||
|
|
||||||
|
// If they hit cancel or left it blank
|
||||||
|
if (!result || !newTitle.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Zotero.Prefs.set('lastRenameAssociatedFile', checkState.value);
|
||||||
|
|
||||||
|
// Rename associated file
|
||||||
|
if (checkState.value) {
|
||||||
|
var renamed = item.renameAttachmentFile(newTitle.value);
|
||||||
|
if (renamed == -1) {
|
||||||
|
var confirmed = confirm(newTitle.value + ' exists. Overwrite existing file?');
|
||||||
|
if (confirmed) {
|
||||||
|
item.renameAttachmentFile(newTitle.value, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// If they said not to overwrite existing file,
|
||||||
|
// start again
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (renamed == -2 || !renamed) {
|
||||||
|
alert(Zotero.getString('pane.item.attachments.rename.error'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newTitle.value != oldTitle) {
|
||||||
|
item.setField('title', newTitle.value);
|
||||||
|
item.save();
|
||||||
|
}
|
||||||
|
]]>
|
||||||
|
</body>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Update Indexed: (Yes|No|Partial) line
|
||||||
|
-->
|
||||||
|
<method name="updateItemIndexedState">
|
||||||
|
<body>
|
||||||
|
<![CDATA[
|
||||||
|
var indexBox = this._id('index-box');
|
||||||
|
var indexStatus = this._id('index-status');
|
||||||
|
var reindexButton = this._id('reindex');
|
||||||
|
|
||||||
|
var status = Zotero.Fulltext.getIndexedState(this.item.id);
|
||||||
|
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 (this.editable &&
|
||||||
|
Zotero.Fulltext.pdfConverterIsRegistered() &&
|
||||||
|
Zotero.Fulltext.canReindex(this.item.id)) {
|
||||||
|
reindexButton.setAttribute('hidden', false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
reindexButton.setAttribute('hidden', true);
|
||||||
|
}
|
||||||
|
]]>
|
||||||
|
</body>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
|
||||||
|
<method name="_id">
|
||||||
|
<parameter name="id"/>
|
||||||
|
<body>
|
||||||
|
<![CDATA[
|
||||||
|
return document.getAnonymousNodes(this)[0].getElementsByAttribute('id', id)[0];
|
||||||
|
]]>
|
||||||
|
</body>
|
||||||
|
</method>
|
||||||
|
</implementation>
|
||||||
|
|
||||||
|
<content>
|
||||||
|
<vbox id="attachment-box" flex="1" orient="vertical"
|
||||||
|
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||||
|
<label id="title"/>
|
||||||
|
<hbox id="go-buttons">
|
||||||
|
<button id="view" flex="1"/>
|
||||||
|
<button id="show" label="&zotero.item.attachment.file.show;" flex="1"/>
|
||||||
|
</hbox>
|
||||||
|
<label id="url" crop="end"/>
|
||||||
|
|
||||||
|
<label id="accessed"/>
|
||||||
|
<label id="pages"/>
|
||||||
|
|
||||||
|
<hbox id="index-box">
|
||||||
|
<label id="index-status"/>
|
||||||
|
<toolbarbutton id="reindex" oncommand="ZoteroPane.reindexItem()"/>
|
||||||
|
</hbox>
|
||||||
|
|
||||||
|
<zoteronoteeditor id="note-editor" notitle="1" flex="1"/>
|
||||||
|
|
||||||
|
<button id="select-button" hidden="true"/>
|
||||||
|
</vbox>
|
||||||
|
</content>
|
||||||
|
</binding>
|
||||||
|
</bindings>
|
|
@ -62,6 +62,11 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for note or attachment
|
||||||
|
if (this.type == 'item') {
|
||||||
|
this.type = this._getTypeFromItem(val);
|
||||||
|
}
|
||||||
|
|
||||||
// Clone object so changes in merge pane don't affect it
|
// Clone object so changes in merge pane don't affect it
|
||||||
this._leftpane.ref = val.clone(true);
|
this._leftpane.ref = val.clone(true);
|
||||||
this._leftpane.original = val;
|
this._leftpane.original = val;
|
||||||
|
@ -83,6 +88,11 @@
|
||||||
else {
|
else {
|
||||||
// TODO: Make sure object is the correct type
|
// TODO: Make sure object is the correct type
|
||||||
|
|
||||||
|
// Check for note or attachment if not already set
|
||||||
|
if (this._leftpane.ref == 'deleted' && this.type == 'item') {
|
||||||
|
this.type = this._getTypeFromItem(val);
|
||||||
|
}
|
||||||
|
|
||||||
// Clone object so changes in merge pane don't affect it
|
// Clone object so changes in merge pane don't affect it
|
||||||
this._rightpane.ref = val.clone(true);
|
this._rightpane.ref = val.clone(true);
|
||||||
this._rightpane.original = val;
|
this._rightpane.original = val;
|
||||||
|
@ -208,6 +218,25 @@
|
||||||
</body>
|
</body>
|
||||||
</method>
|
</method>
|
||||||
|
|
||||||
|
<method name="_getTypeFromItem">
|
||||||
|
<parameter name="obj"/>
|
||||||
|
<body>
|
||||||
|
<![CDATA[
|
||||||
|
if (!(obj instanceof Zotero.Item)) {
|
||||||
|
throw ("obj is not a Zotero.Item in merge.xml");
|
||||||
|
}
|
||||||
|
if (obj.isAttachment()) {
|
||||||
|
return 'attachment';
|
||||||
|
}
|
||||||
|
else if (obj.isNote()) {
|
||||||
|
return 'note';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return 'item';
|
||||||
|
}
|
||||||
|
]]>
|
||||||
|
</body>
|
||||||
|
</method>
|
||||||
|
|
||||||
<method name="_id">
|
<method name="_id">
|
||||||
<parameter name="id"/>
|
<parameter name="id"/>
|
||||||
|
@ -281,6 +310,10 @@
|
||||||
elementName = 'zoteroitembox';
|
elementName = 'zoteroitembox';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'attachment':
|
||||||
|
elementName = 'zoteroattachmentbox';
|
||||||
|
break;
|
||||||
|
|
||||||
case 'note':
|
case 'note':
|
||||||
elementName = 'zoteronoteeditor';
|
elementName = 'zoteronoteeditor';
|
||||||
break;
|
break;
|
||||||
|
@ -314,6 +347,7 @@
|
||||||
|
|
||||||
// Type-specific settings
|
// Type-specific settings
|
||||||
switch (this.type) {
|
switch (this.type) {
|
||||||
|
case 'attachment':
|
||||||
case 'note':
|
case 'note':
|
||||||
objbox.buttonCaption = 'Choose this version';
|
objbox.buttonCaption = 'Choose this version';
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -40,13 +40,12 @@
|
||||||
<field name="displayRelated">false</field>
|
<field name="displayRelated">false</field>
|
||||||
<field name="displayButton">false</field>
|
<field name="displayButton">false</field>
|
||||||
|
|
||||||
|
<field name="buttonCaption"/>
|
||||||
<field name="parentClickHandler"/>
|
<field name="parentClickHandler"/>
|
||||||
<field name="keyDownHandler"/>
|
<field name="keyDownHandler"/>
|
||||||
<field name="commandHandler"/>
|
<field name="commandHandler"/>
|
||||||
<field name="clickHandler"/>
|
<field name="clickHandler"/>
|
||||||
|
|
||||||
<field name="buttonCaption"/>
|
|
||||||
|
|
||||||
<!-- Modes are predefined settings groups for particular tasks -->
|
<!-- Modes are predefined settings groups for particular tasks -->
|
||||||
<field name="_mode">"view"</field>
|
<field name="_mode">"view"</field>
|
||||||
<property name="mode" onget="return this._mode;">
|
<property name="mode" onget="return this._mode;">
|
||||||
|
@ -78,7 +77,9 @@
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'mergeedit':
|
case 'mergeedit':
|
||||||
this.editable = true;
|
// Not currently implemented
|
||||||
|
// (editing works, but value isn't saved)
|
||||||
|
//this.editable = true;
|
||||||
this.keyDownHandler = this.handleKeyDown;
|
this.keyDownHandler = this.handleKeyDown;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -146,7 +147,6 @@
|
||||||
var parentbox = this._id('citeLabel');
|
var parentbox = this._id('citeLabel');
|
||||||
var textbox = this._id('noteField');
|
var textbox = this._id('noteField');
|
||||||
var button = this._id('goButton');
|
var button = this._id('goButton');
|
||||||
var button = this._id('goButton');
|
|
||||||
|
|
||||||
if (this.editable) {
|
if (this.editable) {
|
||||||
textbox.removeAttribute('readonly');
|
textbox.removeAttribute('readonly');
|
||||||
|
|
|
@ -34,37 +34,45 @@
|
||||||
<field name="_loadHandler"/>
|
<field name="_loadHandler"/>
|
||||||
<field name="_commandString"/>
|
<field name="_commandString"/>
|
||||||
<field name="_eventHandler"/>
|
<field name="_eventHandler"/>
|
||||||
|
<field name="_editor"/>
|
||||||
|
<field name="_value"/>
|
||||||
<field name="_timer"/>
|
<field name="_timer"/>
|
||||||
<field name="_focus"/>
|
<field name="_focus"/>
|
||||||
|
<field name="_constructed"/>
|
||||||
|
<field name="_loadOnConstruct"/>
|
||||||
|
|
||||||
<constructor><![CDATA[
|
<constructor><![CDATA[
|
||||||
this.mode = this.getAttribute('mode');
|
this.mode = this.getAttribute('mode');
|
||||||
|
|
||||||
this._iframe = document.getAnonymousElementByAttribute(this, "anonid", "rt-view");
|
this._iframe = document.getAnonymousElementByAttribute(this, "anonid", "rt-view");
|
||||||
this._editor = null;
|
|
||||||
this._value = null;
|
this._rtfMap = {
|
||||||
|
"\\":"\\\\",
|
||||||
this._rtfMap = {
|
"<em>":"\\i ",
|
||||||
"\\":"\\\\",
|
"</em>":"\\i0 ",
|
||||||
"<em>":"\\i ",
|
"<i>":"\\i ",
|
||||||
"</em>":"\\i0 ",
|
"</i>":"\\i0 ",
|
||||||
"<i>":"\\i ",
|
"<strong>":"\\b ",
|
||||||
"</i>":"\\i0 ",
|
"</strong>":"\\b0 ",
|
||||||
"<strong>":"\\b ",
|
"<b>":"\\b ",
|
||||||
"</strong>":"\\b0 ",
|
"</b>":"\\b0 ",
|
||||||
"<b>":"\\b ",
|
"<u>":"\\ul ",
|
||||||
"</b>":"\\b0 ",
|
"</u>":"\\ul0 ",
|
||||||
"<u>":"\\ul ",
|
"<br />":"\x0B",
|
||||||
"</u>":"\\ul0 ",
|
"<sup>":"\\super ",
|
||||||
"<br />":"\x0B",
|
"</sup>":"\\super0 ",
|
||||||
"<sup>":"\\super ",
|
"<sub>":"\\sub ",
|
||||||
"</sup>":"\\super0 ",
|
"</sub>":"\\sub0 ",
|
||||||
"<sub>":"\\sub ",
|
// there's no way to mimic a tab stop in CSS without
|
||||||
"</sub>":"\\sub0 ",
|
// tables, which wouldn't work here.
|
||||||
// there's no way to mimic a tab stop in CSS without
|
'<span class="tab"> </span>':"\t"
|
||||||
// tables, which wouldn't work here.
|
};
|
||||||
'<span class="tab"> </span>':"\t"
|
|
||||||
};
|
this._constructed = true;
|
||||||
|
|
||||||
|
if (this._loadOnConstruct) {
|
||||||
|
this._load();
|
||||||
|
}
|
||||||
]]></constructor>
|
]]></constructor>
|
||||||
|
|
||||||
<property name="mode">
|
<property name="mode">
|
||||||
|
@ -178,7 +186,11 @@
|
||||||
Zotero.debug('No editor yet');
|
Zotero.debug('No editor yet');
|
||||||
|
|
||||||
this._value = val;
|
this._value = val;
|
||||||
if (!this._loaded) {
|
if (!this._constructed) {
|
||||||
|
Zotero.debug('Styled textbox not yet constructed', 2);
|
||||||
|
this._loadOnConstruct = true;
|
||||||
|
}
|
||||||
|
else if (!this._loaded) {
|
||||||
this._load();
|
this._load();
|
||||||
}
|
}
|
||||||
return ;
|
return ;
|
||||||
|
|
|
@ -42,13 +42,6 @@ var Zotero_Merge_Window = new function () {
|
||||||
|
|
||||||
switch (_mergeGroup.type) {
|
switch (_mergeGroup.type) {
|
||||||
case 'item':
|
case 'item':
|
||||||
var firstObj = _objects[0][0] == 'deleted' ? _objects[0][1] : _objects[0][0];
|
|
||||||
if (firstObj.isNote()) {
|
|
||||||
_mergeGroup.type = 'note';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_mergeGroup.type = 'item';
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -122,14 +115,23 @@ var Zotero_Merge_Window = new function () {
|
||||||
// Adjust counter
|
// Adjust counter
|
||||||
_numObjects.value = _pos + 1;
|
_numObjects.value = _pos + 1;
|
||||||
|
|
||||||
_mergeGroup.left = _objects[_pos][0];
|
try {
|
||||||
_mergeGroup.right = _objects[_pos][1];
|
_mergeGroup.left = _objects[_pos][0];
|
||||||
|
_mergeGroup.right = _objects[_pos][1];
|
||||||
// Restore previously merged object into merge pane
|
|
||||||
if (_merged[_pos]) {
|
// Restore previously merged object into merge pane
|
||||||
_mergeGroup.merge = _merged[_pos].ref;
|
if (_merged[_pos]) {
|
||||||
_mergeGroup.leftpane.removeAttribute("selected");
|
_mergeGroup.merge = _merged[_pos].ref;
|
||||||
_mergeGroup.rightpane.removeAttribute("selected");
|
_mergeGroup.leftpane.removeAttribute("selected");
|
||||||
|
_mergeGroup.rightpane.removeAttribute("selected");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
var prompt = Components.classes["@mozilla.org/network/default-prompt;1"]
|
||||||
|
.createInstance(Components.interfaces.nsIPrompt);
|
||||||
|
prompt.alert(Zotero.getString('general.error'), e);
|
||||||
|
_wizard.getButton('cancel').click();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_mergeGroup.type == 'item') {
|
if (_mergeGroup.type == 'item') {
|
||||||
|
|
|
@ -50,7 +50,6 @@ var ZoteroPane = new function()
|
||||||
this.updateTagFilter = updateTagFilter;
|
this.updateTagFilter = updateTagFilter;
|
||||||
this.onCollectionSelected = onCollectionSelected;
|
this.onCollectionSelected = onCollectionSelected;
|
||||||
this.itemSelected = itemSelected;
|
this.itemSelected = itemSelected;
|
||||||
this.updateItemIndexedState = updateItemIndexedState;
|
|
||||||
this.reindexItem = reindexItem;
|
this.reindexItem = reindexItem;
|
||||||
this.duplicateSelectedItem = duplicateSelectedItem;
|
this.duplicateSelectedItem = duplicateSelectedItem;
|
||||||
this.deleteSelectedItem = deleteSelectedItem;
|
this.deleteSelectedItem = deleteSelectedItem;
|
||||||
|
@ -83,7 +82,6 @@ var ZoteroPane = new function()
|
||||||
this.addAttachmentFromPage = addAttachmentFromPage;
|
this.addAttachmentFromPage = addAttachmentFromPage;
|
||||||
this.viewAttachment = viewAttachment;
|
this.viewAttachment = viewAttachment;
|
||||||
this.viewSelectedAttachment = viewSelectedAttachment;
|
this.viewSelectedAttachment = viewSelectedAttachment;
|
||||||
this.showSelectedAttachmentInFilesystem = showSelectedAttachmentInFilesystem;
|
|
||||||
this.showAttachmentNotFoundDialog = showAttachmentNotFoundDialog;
|
this.showAttachmentNotFoundDialog = showAttachmentNotFoundDialog;
|
||||||
this.relinkAttachment = relinkAttachment;
|
this.relinkAttachment = relinkAttachment;
|
||||||
this.reportErrors = reportErrors;
|
this.reportErrors = reportErrors;
|
||||||
|
@ -797,12 +795,7 @@ var ZoteroPane = new function()
|
||||||
|
|
||||||
if(item.ref.isNote()) {
|
if(item.ref.isNote()) {
|
||||||
var noteEditor = document.getElementById('zotero-note-editor');
|
var noteEditor = document.getElementById('zotero-note-editor');
|
||||||
if (this.itemsView.readOnly) {
|
noteEditor.mode = this.itemsView.readOnly ? 'view' : 'edit';
|
||||||
noteEditor.mode = 'view';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
noteEditor.mode = 'edit';
|
|
||||||
}
|
|
||||||
|
|
||||||
// If loading new or different note, disable undo while we repopulate the text field
|
// If loading new or different note, disable undo while we repopulate the text field
|
||||||
// so Undo doesn't end up clearing the field. This also ensures that Undo doesn't
|
// so Undo doesn't end up clearing the field. This also ensures that Undo doesn't
|
||||||
|
@ -828,165 +821,9 @@ var ZoteroPane = new function()
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(item.ref.isAttachment()) {
|
else if(item.ref.isAttachment()) {
|
||||||
// DEBUG: this is annoying -- we really want to use an abstracted
|
var attachmentBox = document.getElementById('zotero-attachment-box');
|
||||||
// version of createValueElement() from itemPane.js
|
attachmentBox.mode = this.itemsView.readOnly ? 'view' : 'edit';
|
||||||
// (ideally in an XBL binding)
|
attachmentBox.item = item.ref;
|
||||||
|
|
||||||
// Wrap title to multiple lines if necessary
|
|
||||||
var label = document.getElementById('zotero-attachment-label');
|
|
||||||
while (label.hasChildNodes())
|
|
||||||
{
|
|
||||||
label.removeChild(label.firstChild);
|
|
||||||
}
|
|
||||||
var val = item.getField('title');
|
|
||||||
|
|
||||||
var firstSpace = val.indexOf(" ");
|
|
||||||
// Crop long uninterrupted text
|
|
||||||
if ((firstSpace == -1 && val.length > 29 ) || firstSpace > 29)
|
|
||||||
{
|
|
||||||
label.setAttribute('crop', 'end');
|
|
||||||
label.setAttribute('value', val);
|
|
||||||
}
|
|
||||||
// Create a <description> element, essentially
|
|
||||||
else
|
|
||||||
{
|
|
||||||
label.removeAttribute('value');
|
|
||||||
label.appendChild(document.createTextNode(val));
|
|
||||||
}
|
|
||||||
|
|
||||||
// For the time being, use a silly little popup
|
|
||||||
label.className = 'zotero-clicky';
|
|
||||||
label.onclick = function(event){
|
|
||||||
var nsIPS = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
|
|
||||||
.getService(Components.interfaces.nsIPromptService);
|
|
||||||
|
|
||||||
var newTitle = { value: val };
|
|
||||||
var checkState = { value: Zotero.Prefs.get('lastRenameAssociatedFile') };
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
// Don't show "Rename associated file" option for
|
|
||||||
// linked URLs
|
|
||||||
if (item.ref.getAttachmentLinkMode() ==
|
|
||||||
Zotero.Attachments.LINK_MODE_LINKED_URL) {
|
|
||||||
var result = nsIPS.prompt(
|
|
||||||
window,
|
|
||||||
'',
|
|
||||||
Zotero.getString('pane.item.attachments.rename.title'),
|
|
||||||
newTitle,
|
|
||||||
null,
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
|
|
||||||
// If they hit cancel or left it blank
|
|
||||||
if (!result || !newTitle.value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = nsIPS.prompt(
|
|
||||||
window,
|
|
||||||
'',
|
|
||||||
Zotero.getString('pane.item.attachments.rename.title'),
|
|
||||||
newTitle,
|
|
||||||
Zotero.getString('pane.item.attachments.rename.renameAssociatedFile'),
|
|
||||||
checkState
|
|
||||||
);
|
|
||||||
|
|
||||||
// If they hit cancel or left it blank
|
|
||||||
if (!result || !newTitle.value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Zotero.Prefs.set('lastRenameAssociatedFile', checkState.value);
|
|
||||||
|
|
||||||
// Rename associated file
|
|
||||||
if (checkState.value) {
|
|
||||||
var renamed = item.ref.renameAttachmentFile(newTitle.value);
|
|
||||||
if (renamed == -1) {
|
|
||||||
var confirmed = confirm(newTitle.value + ' exists. Overwrite existing file?');
|
|
||||||
if (confirmed) {
|
|
||||||
item.ref.renameAttachmentFile(newTitle.value, true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// If they said not to overwrite existing file,
|
|
||||||
// start again
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (renamed == -2 || !renamed) {
|
|
||||||
alert(Zotero.getString('pane.item.attachments.rename.error'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newTitle.value != val) {
|
|
||||||
item.ref.setField('title', newTitle.value);
|
|
||||||
item.ref.save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var isImportedURL = item.ref.getAttachmentLinkMode() == Zotero.Attachments.LINK_MODE_IMPORTED_URL;
|
|
||||||
|
|
||||||
// Metadata for URL's
|
|
||||||
if (item.ref.getAttachmentLinkMode() == Zotero.Attachments.LINK_MODE_LINKED_URL
|
|
||||||
|| isImportedURL)
|
|
||||||
{
|
|
||||||
// "View Page"/"View Snapshot" label
|
|
||||||
if (isImportedURL)
|
|
||||||
{
|
|
||||||
var str = Zotero.getString('pane.item.attachments.view.snapshot');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var str = Zotero.getString('pane.item.attachments.view.link');
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById('zotero-attachment-show').setAttribute('hidden', !isImportedURL);
|
|
||||||
|
|
||||||
// URL
|
|
||||||
document.getElementById('zotero-attachment-url').setAttribute('value', item.getField('url'));
|
|
||||||
document.getElementById('zotero-attachment-url').setAttribute('hidden', false);
|
|
||||||
// Access date
|
|
||||||
document.getElementById('zotero-attachment-accessed').setAttribute('value',
|
|
||||||
Zotero.getString('itemFields.accessDate') + ': '
|
|
||||||
+ Zotero.Date.sqlToDate(item.getField('accessDate'), true).toLocaleString());
|
|
||||||
document.getElementById('zotero-attachment-accessed').setAttribute('hidden', false);
|
|
||||||
}
|
|
||||||
// Metadata for files
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var str = Zotero.getString('pane.item.attachments.view.file');
|
|
||||||
document.getElementById('zotero-attachment-show').setAttribute('hidden', false);
|
|
||||||
document.getElementById('zotero-attachment-url').setAttribute('hidden', true);
|
|
||||||
document.getElementById('zotero-attachment-accessed').setAttribute('hidden', true);
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById('zotero-attachment-view').setAttribute('label', str);
|
|
||||||
|
|
||||||
// Display page count
|
|
||||||
var pages = Zotero.Fulltext.getPages(item.ref.id);
|
|
||||||
var pages = pages ? pages.total : null;
|
|
||||||
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.mode = 'edit';
|
|
||||||
noteEditor.parent = null;
|
|
||||||
noteEditor.item = item.ref;
|
|
||||||
|
|
||||||
document.getElementById('zotero-item-pane-content').selectedIndex = 3;
|
document.getElementById('zotero-item-pane-content').selectedIndex = 3;
|
||||||
}
|
}
|
||||||
|
@ -1015,48 +852,6 @@ 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.id);
|
|
||||||
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.id)) {
|
|
||||||
reindexButton.setAttribute('hidden', false);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
reindexButton.setAttribute('hidden', true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function reindexItem() {
|
function reindexItem() {
|
||||||
var items = this.getSelectedItems();
|
var items = this.getSelectedItems();
|
||||||
if (!items) {
|
if (!items) {
|
||||||
|
@ -1070,7 +865,7 @@ var ZoteroPane = new function()
|
||||||
var itemID = items[i].id;
|
var itemID = items[i].id;
|
||||||
Zotero.Fulltext.indexItems(itemID, true);
|
Zotero.Fulltext.indexItems(itemID, true);
|
||||||
}
|
}
|
||||||
this.updateItemIndexedState();
|
document.getElementById('zotero-attachment-box').updateItemIndexedState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2100,13 +1895,13 @@ var ZoteroPane = new function()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function viewAttachment(itemID, event) {
|
function viewAttachment(itemID, event, noLocateOnMissing) {
|
||||||
var attachment = Zotero.Items.get(itemID);
|
var attachment = Zotero.Items.get(itemID);
|
||||||
if (!attachment.isAttachment()) {
|
if (!attachment.isAttachment()) {
|
||||||
throw ("Item " + itemID + " is not an attachment in ZoteroPane.viewAttachment()");
|
throw ("Item " + itemID + " is not an attachment in ZoteroPane.viewAttachment()");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attachment.getAttachmentLinkMode() == Zotero.Attachments.LINK_MODE_LINKED_URL) {
|
if (attachment.attachmentLinkMode == Zotero.Attachments.LINK_MODE_LINKED_URL) {
|
||||||
this.loadURI(attachment.getField('url'), event);
|
this.loadURI(attachment.getField('url'), event);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2146,61 +1941,67 @@ var ZoteroPane = new function()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.showAttachmentNotFoundDialog(itemID);
|
this.showAttachmentNotFoundDialog(itemID, noLocateOnMissing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function viewSelectedAttachment(event)
|
function viewSelectedAttachment(event, noLocateOnMissing)
|
||||||
{
|
{
|
||||||
if (this.itemsView && this.itemsView.selection.count == 1) {
|
if (this.itemsView && this.itemsView.selection.count == 1) {
|
||||||
this.viewAttachment(this.getSelectedItems(true)[0], event);
|
this.viewAttachment(this.getSelectedItems(true)[0], event, noLocateOnMissing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function showSelectedAttachmentInFilesystem()
|
this.showAttachmentInFilesystem = function (itemID, noLocateOnMissing) {
|
||||||
{
|
var attachment = Zotero.Items.get(itemID)
|
||||||
if (this.itemsView && this.itemsView.selection.count == 1) {
|
if (attachment.attachmentLinkMode != Zotero.Attachments.LINK_MODE_LINKED_URL) {
|
||||||
var attachment = this.getSelectedItems()[0];
|
var file = attachment.getFile();
|
||||||
|
if (file){
|
||||||
if (attachment.getAttachmentLinkMode() != Zotero.Attachments.LINK_MODE_LINKED_URL)
|
try {
|
||||||
{
|
file.reveal();
|
||||||
var file = attachment.getFile();
|
}
|
||||||
if (file){
|
catch (e) {
|
||||||
|
// On platforms that don't support nsILocalFile.reveal() (e.g. Linux),
|
||||||
|
// "double-click" the parent directory
|
||||||
try {
|
try {
|
||||||
file.reveal();
|
var parent = file.parent.QueryInterface(Components.interfaces.nsILocalFile);
|
||||||
|
parent.launch();
|
||||||
}
|
}
|
||||||
|
// If launch also fails, try the OS handler
|
||||||
catch (e) {
|
catch (e) {
|
||||||
// On platforms that don't support nsILocalFile.reveal() (e.g. Linux),
|
var uri = Components.classes["@mozilla.org/network/io-service;1"].
|
||||||
// "double-click" the parent directory
|
getService(Components.interfaces.nsIIOService).
|
||||||
try {
|
newFileURI(parent);
|
||||||
var parent = file.parent.QueryInterface(Components.interfaces.nsILocalFile);
|
var protocolService =
|
||||||
parent.launch();
|
Components.classes["@mozilla.org/uriloader/external-protocol-service;1"].
|
||||||
}
|
getService(Components.interfaces.nsIExternalProtocolService);
|
||||||
// If launch also fails, try the OS handler
|
protocolService.loadUrl(uri);
|
||||||
catch (e) {
|
|
||||||
var uri = Components.classes["@mozilla.org/network/io-service;1"].
|
|
||||||
getService(Components.interfaces.nsIIOService).
|
|
||||||
newFileURI(parent);
|
|
||||||
var protocolService =
|
|
||||||
Components.classes["@mozilla.org/uriloader/external-protocol-service;1"].
|
|
||||||
getService(Components.interfaces.nsIExternalProtocolService);
|
|
||||||
protocolService.loadUrl(uri);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
this.showAttachmentNotFoundDialog(attachment.id)
|
else {
|
||||||
}
|
this.showAttachmentNotFoundDialog(attachment.id, noLocateOnMissing)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function showAttachmentNotFoundDialog(itemID) {
|
function showAttachmentNotFoundDialog(itemID, noLocate) {
|
||||||
var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
|
var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
|
||||||
createInstance(Components.interfaces.nsIPromptService);
|
createInstance(Components.interfaces.nsIPromptService);
|
||||||
|
|
||||||
|
|
||||||
|
// Don't show Locate button
|
||||||
|
if (noLocate) {
|
||||||
|
var index = ps.alert(null,
|
||||||
|
Zotero.getString('pane.item.attachments.fileNotFound.title'),
|
||||||
|
Zotero.getString('pane.item.attachments.fileNotFound.text')
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var buttonFlags = (ps.BUTTON_POS_0) * (ps.BUTTON_TITLE_IS_STRING)
|
var buttonFlags = (ps.BUTTON_POS_0) * (ps.BUTTON_TITLE_IS_STRING)
|
||||||
+ (ps.BUTTON_POS_1) * (ps.BUTTON_TITLE_CANCEL);
|
+ (ps.BUTTON_POS_1) * (ps.BUTTON_TITLE_CANCEL);
|
||||||
var index = ps.confirmEx(null,
|
var index = ps.confirmEx(null,
|
||||||
|
|
|
@ -379,25 +379,7 @@
|
||||||
<button id="zotero-view-note-button" label="&zotero.notes.separate;" oncommand="ZoteroPane.openNoteWindow(this.getAttribute('noteID')); if(this.hasAttribute('sourceID')) ZoteroPane.selectItem(this.getAttribute('sourceID'));"/>
|
<button id="zotero-view-note-button" label="&zotero.notes.separate;" oncommand="ZoteroPane.openNoteWindow(this.getAttribute('noteID')); if(this.hasAttribute('sourceID')) ZoteroPane.selectItem(this.getAttribute('sourceID'));"/>
|
||||||
</vbox>
|
</vbox>
|
||||||
<!-- Attachment info pane -->
|
<!-- Attachment info pane -->
|
||||||
<vbox id="zotero-view-attachment" flex="1">
|
<zoteroattachmentbox id="zotero-attachment-box" flex="1"/>
|
||||||
<label id="zotero-attachment-label"/>
|
|
||||||
<hbox>
|
|
||||||
<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>
|
|
||||||
<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>
|
|
||||||
|
|
||||||
<zoteronoteeditor id="zotero-attachment-note-editor" notitle="1" flex="1"/>
|
|
||||||
</vbox>
|
|
||||||
</deck>
|
</deck>
|
||||||
</groupbox>
|
</groupbox>
|
||||||
</vbox>
|
</vbox>
|
||||||
|
|
|
@ -2949,22 +2949,52 @@ Zotero.Item.prototype.diff = function (item, includeMatches, ignoreOnlyDateModif
|
||||||
var diff = [];
|
var diff = [];
|
||||||
var thisData = this.serialize();
|
var thisData = this.serialize();
|
||||||
var otherData = item.serialize();
|
var otherData = item.serialize();
|
||||||
|
|
||||||
var numDiffs = Zotero.Items.diff(thisData, otherData, diff, includeMatches);
|
var numDiffs = Zotero.Items.diff(thisData, otherData, diff, includeMatches);
|
||||||
|
|
||||||
diff[0].creators = [];
|
diff[0].creators = [];
|
||||||
diff[1].creators = [];
|
diff[1].creators = [];
|
||||||
// TODO: creators
|
// TODO: creators?
|
||||||
|
// TODO: tags?
|
||||||
// TODO: attachments
|
// TODO: related?
|
||||||
|
|
||||||
// TODO: notes
|
|
||||||
|
|
||||||
// TODO: tags
|
|
||||||
|
|
||||||
// TODO: related
|
|
||||||
|
|
||||||
// TODO: annotations
|
// TODO: annotations
|
||||||
|
|
||||||
|
var changed = false;
|
||||||
|
|
||||||
|
if (thisData.attachment) {
|
||||||
|
for (var field in thisData.attachment) {
|
||||||
|
changed = thisData.attachment[field] != otherData.attachment[field];
|
||||||
|
if (includeMatches || changed) {
|
||||||
|
if (!diff[0].attachment) {
|
||||||
|
diff[0].attachment = {};
|
||||||
|
diff[1].attachment = {};
|
||||||
|
}
|
||||||
|
diff[0].attachment[field] = thisData.attachment[field];
|
||||||
|
diff[1].attachment[field] = otherData.attachment[field];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
|
numDiffs++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thisData.note != undefined) {
|
||||||
|
changed = thisData.note != otherData.note;
|
||||||
|
if (includeMatches || changed) {
|
||||||
|
diff[0].note = thisData.note;
|
||||||
|
diff[1].note = otherData.note;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
|
numDiffs++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Zotero.debug(thisData);
|
||||||
|
//Zotero.debug(otherData);
|
||||||
|
//Zotero.debug(diff);
|
||||||
|
|
||||||
// DEBUG: ignoreOnlyDateModified wouldn't work if includeMatches was set?
|
// DEBUG: ignoreOnlyDateModified wouldn't work if includeMatches was set?
|
||||||
if (numDiffs == 0 ||
|
if (numDiffs == 0 ||
|
||||||
(ignoreOnlyDateModified && numDiffs == 1
|
(ignoreOnlyDateModified && numDiffs == 1
|
||||||
|
@ -2980,10 +3010,6 @@ Zotero.Item.prototype.diff = function (item, includeMatches, ignoreOnlyDateModif
|
||||||
* Returns an unsaved copy of the item
|
* Returns an unsaved copy of the item
|
||||||
*/
|
*/
|
||||||
Zotero.Item.prototype.clone = function(includePrimary) {
|
Zotero.Item.prototype.clone = function(includePrimary) {
|
||||||
if (this.isAttachment()) {
|
|
||||||
throw ('Cloning attachment items not supported in Zotero.Item.clone()');
|
|
||||||
}
|
|
||||||
|
|
||||||
Zotero.debug('Cloning item ' + this.id);
|
Zotero.debug('Cloning item ' + this.id);
|
||||||
|
|
||||||
Zotero.DB.beginTransaction();
|
Zotero.DB.beginTransaction();
|
||||||
|
@ -3004,23 +3030,15 @@ Zotero.Item.prototype.clone = function(includePrimary) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note
|
for (var field in obj.fields) {
|
||||||
if (this.isNote()) {
|
var fieldID = Zotero.ItemFields.getID(field);
|
||||||
newItem.setNote(this.getNote());
|
if (fieldID && Zotero.ItemFields.isValidForType(fieldID, itemTypeID)) {
|
||||||
var parent = this.getSource();
|
newItem.setField(field, obj.fields[field]);
|
||||||
if (parent) {
|
|
||||||
newItem.setSource(parent);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Regular item
|
// Regular item
|
||||||
else {
|
if (this.isRegularItem()) {
|
||||||
for (var field in obj.fields) {
|
|
||||||
var fieldID = Zotero.ItemFields.getID(field);
|
|
||||||
if (fieldID && Zotero.ItemFields.isValidForType(fieldID, itemTypeID)) {
|
|
||||||
newItem.setField(field, obj.fields[field]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (includePrimary) {
|
if (includePrimary) {
|
||||||
// newItem = loaded from db
|
// newItem = loaded from db
|
||||||
// obj = in-memory
|
// obj = in-memory
|
||||||
|
@ -3054,6 +3072,21 @@ Zotero.Item.prototype.clone = function(includePrimary) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
newItem.setNote(this.getNote());
|
||||||
|
var parent = this.getSource();
|
||||||
|
if (parent) {
|
||||||
|
newItem.setSource(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isAttachment()) {
|
||||||
|
newItem.attachmentLinkMode = this.attachmentLinkMode;
|
||||||
|
newItem.attachmentMIMEType = this.attachmentMIMEType;
|
||||||
|
newItem.attachmentCharset = this.attachmentCharset;
|
||||||
|
newItem.attachmentPath = this.attachmentPath;
|
||||||
|
newItem.attachmentSyncState = this.attachmentSyncState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (obj.tags) {
|
if (obj.tags) {
|
||||||
for each(var tag in obj.tags) {
|
for each(var tag in obj.tags) {
|
||||||
|
|
|
@ -1626,11 +1626,6 @@ Zotero.Sync.Server.Data = new function() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (obj.isAttachment()) {
|
|
||||||
var msg = "Reconciliation unimplemented for attachment items";
|
|
||||||
alert(msg);
|
|
||||||
throw(msg);
|
|
||||||
}
|
|
||||||
reconcile = true;
|
reconcile = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1894,7 +1889,6 @@ Zotero.Sync.Server.Data = new function() {
|
||||||
default:
|
default:
|
||||||
alert('Delete reconciliation unimplemented for ' + types);
|
alert('Delete reconciliation unimplemented for ' + types);
|
||||||
throw ('Delete reconciliation unimplemented for ' + types);
|
throw ('Delete reconciliation unimplemented for ' + types);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
36
chrome/skin/default/zotero/bindings/attachmentbox.css
Normal file
36
chrome/skin/default/zotero/bindings/attachmentbox.css
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/* Don't collapse blank attachment titles, since it prevents renaming */
|
||||||
|
#title
|
||||||
|
{
|
||||||
|
min-height: 1.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#view, #show
|
||||||
|
{
|
||||||
|
list-style-image: url('chrome://zotero/skin/toolbar-go-arrow.png');
|
||||||
|
-moz-box-direction: reverse;
|
||||||
|
-moz-box-flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#index-box
|
||||||
|
{
|
||||||
|
-moz-box-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#reindex
|
||||||
|
{
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
list-style-image: url(chrome://zotero/skin/arrow_refresh.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
#reindex .toolbarbutton-icon
|
||||||
|
{
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#index-box > button
|
||||||
|
{
|
||||||
|
font-size: .95em;
|
||||||
|
padding: 0;
|
||||||
|
}
|
|
@ -274,58 +274,12 @@
|
||||||
list-style-image: url('chrome://zotero/skin/search-cancel-active.png');
|
list-style-image: url('chrome://zotero/skin/search-cancel-active.png');
|
||||||
}
|
}
|
||||||
|
|
||||||
#zotero-attachment-view, #zotero-attachment-show
|
|
||||||
{
|
|
||||||
list-style-image: url('chrome://zotero/skin/toolbar-go-arrow.png');
|
|
||||||
-moz-box-direction: reverse;
|
|
||||||
-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-view-item > vbox
|
#zotero-view-item > vbox
|
||||||
{
|
{
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't collapse blank attachment labels, since it prevents renaming */
|
|
||||||
#zotero-attachment-label
|
|
||||||
{
|
|
||||||
min-height: 1.25em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#zotero-attachment-index-box
|
|
||||||
{
|
|
||||||
-moz-box-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#zotero-attachment-index-box > button
|
|
||||||
{
|
|
||||||
font-size: .95em;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#zotero-splitter
|
#zotero-splitter
|
||||||
{
|
{
|
||||||
border-top: none;
|
border-top: none;
|
||||||
|
|
|
@ -68,6 +68,12 @@ textbox[type="styled"]
|
||||||
-moz-binding: url('chrome://zotero/content/bindings/styled-textbox.xml#styled-textbox');
|
-moz-binding: url('chrome://zotero/content/bindings/styled-textbox.xml#styled-textbox');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
zoteroattachmentbox
|
||||||
|
{
|
||||||
|
-moz-binding: url('chrome://zotero/content/bindings/attachmentbox.xml#attachment-box');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
zoteronoteeditor
|
zoteronoteeditor
|
||||||
{
|
{
|
||||||
-moz-binding: url('chrome://zotero/content/bindings/noteeditor.xml#note-editor');
|
-moz-binding: url('chrome://zotero/content/bindings/noteeditor.xml#note-editor');
|
||||||
|
|
Loading…
Reference in New Issue
Block a user