zotero/chrome/content/zotero/bindings/attachmentbox.xml

551 lines
16 KiB
XML

<?xml version="1.0"?>
<!--
***** BEGIN LICENSE BLOCK *****
Copyright © 2009 Center for History and New Media
George Mason University, Fairfax, Virginia, USA
http://zotero.org
This file is part of Zotero.
Zotero is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Zotero is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with Zotero. If not, see <http://www.gnu.org/licenses/>.
***** 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"/>
<stylesheet src="chrome://zotero-platform/content/attachmentbox.css"/>
</resources>
<implementation>
<!--
Public properties
-->
<field name="editable">false</field>
<field name="clickableLink">false</field>
<field name="displayButton">false</field>
<field name="displayNote">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[
Zotero.debug("Setting mode to '" + val + "'");
this.editable = false;
this.displayURL = false;
this.displayFileName = false;
this.clickableLink = false;
this.displayAccessed = false;
this.displayPages = false;
this.displayDateModified = false;
this.displayIndexed = false;
this.displayNote = false;
this.displayNoteIfEmpty = false;
switch (val) {
case 'view':
this.displayURL = true;
this.displayFileName = true;
this.clickableLink = true;
this.displayAccessed = true;
this.displayPages = true;
this.displayIndexed = true;
this.displayNote = true;
this.displayDateModified = true;
break;
case 'edit':
this.editable = true;
this.displayURL = true;
this.displayFileName = true;
this.clickableLink = true;
this.displayAccessed = true;
this.displayPages = true;
this.displayIndexed = true;
this.displayNote = true;
this.displayNoteIfEmpty = true;
this.displayDateModified = true;
break;
case 'merge':
this.displayURL = true;
this.displayFileName = true;
this.displayAccessed = true;
this.displayNote = true;
this.displayButton = true;
this.displayDateModified = true;
break;
case 'mergeedit':
this.editable = true;
this.displayURL = true;
this.displayFileName = true;
this.displayAccessed = true;
this.displayNote = true;
// Notes aren't currently editable in mergeedit pane
this.displayNoteIfEmpty = false;
this.displayDateModified = true;
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 fileNameRow = this._id('fileNameRow');
var urlField = this._id('url');
var accessed = this._id('accessedRow');
var pagesRow = this._id('pagesRow');
var dateModifiedRow = this._id('dateModifiedRow');
var indexStatusRow = this._id('indexStatusRow');
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');
if (typeof val != 'string') {
val += "";
}
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);
}
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) {
// URL
if (this.displayURL) {
var urlSpec = this.item.getField('url');
urlField.setAttribute('value', urlSpec);
urlField.setAttribute('hidden', false);
if (this.clickableLink) {
urlField.onclick = function (event) {
ZoteroPane_Local.loadURI(this.value, event)
};
urlField.className = 'text-link';
}
else {
urlField.className = '';
}
urlField.hidden = false;
}
else {
urlField.hidden = true;
}
// Access date
if (this.displayAccessed) {
this._id("accessed-label").value = Zotero.getString('itemFields.accessDate')+":";
this._id("accessed").value = Zotero.Date.sqlToDate(
this.item.getField('accessDate'), true
).toLocaleString();
accessed.hidden = false;
}
else {
accessed.hidden = true;
}
}
// Metadata for files
else {
urlField.hidden = true;
accessed.hidden = true;
}
if (this.item.attachmentLinkMode
!= Zotero.Attachments.LINK_MODE_LINKED_URL
&& this.displayFileName) {
// TODO: localize
var fileName = this.item.getFilename();
if (fileName) {
// TODO: localize
this._id("fileName-label").value = "Filename:";
this._id("fileName").value = fileName;
fileNameRow.hidden = false;
}
else {
fileNameRow.hidden = true;
}
}
else {
fileNameRow.hidden = true;
}
// Page count
if (this.displayPages) {
var pages = Zotero.Fulltext.getPages(this.item.id);
var pages = pages ? pages.total : null;
if (pages) {
// TODO: localize colon
this._id("pages-label").value = Zotero.getString('itemFields.pages') + ':';
this._id("pages").value = pages;
pagesRow.hidden = false;
}
else {
pagesRow.hidden = true;
}
}
else {
pagesRow.hidden = true;
}
if (this.displayDateModified) {
this._id("dateModified-label").value = Zotero.getString('itemFields.dateModified')+':';
var mtime = this.item.attachmentModificationTime;
if (mtime) {
this._id("dateModified").value = new Date(mtime).toLocaleString();
}
// Use the item's mod time as a backup (e.g., when sync
// passes in the mod time for the nonexistent remote file)
else {
this._id("dateModified").value = Zotero.Date.sqlToDate(
this.item.getField('dateModified'), true
).toLocaleString();
}
dateModifiedRow.hidden = false;
}
else {
dateModifiedRow.hidden = true;
}
// Full-text index information
if (this.displayIndexed) {
this.updateItemIndexedState();
indexStatusRow.hidden = false;
}
else {
indexStatusRow.hidden = true;
}
// Note editor
var noteEditor = this._id('note-editor');
if (this.displayNote) {
if (this.displayNoteIfEmpty || this.item.getNote() != '') {
Zotero.debug("setting links on top");
noteEditor.linksOnTop = true;
noteEditor.hidden = false;
// 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;
}
}
else {
noteEditor.hidden = true;
}
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 = nsIPS.confirm(
window,
'',
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) {
nsIPS.alert(
window,
Zotero.getString('general.error'),
Zotero.getString('pane.item.attachments.rename.error')
);
return;
}
else if (!renamed) {
nsIPS.alert(
window,
Zotero.getString('pane.item.attachments.fileNotFound.title'),
Zotero.getString('pane.item.attachments.fileNotFound.text')
);
}
}
break;
}
if (newTitle.value != oldTitle) {
item.setField('title', newTitle.value);
item.save();
}
]]>
</body>
</method>
<method name="onViewClick">
<parameter name="event"/>
<body>
<![CDATA[
ZoteroPane_Local.viewAttachment(this.item.id, event, !this.editable);
]]>
</body>
</method>
<method name="onShowClick">
<parameter name="event"/>
<body>
<![CDATA[
ZoteroPane_Local.showAttachmentInFilesystem(this.item.id, event.originalTarget, !this.editable);
]]>
</body>
</method>
<!--
Update Indexed: (Yes|No|Partial) line
-->
<method name="updateItemIndexedState">
<body>
<![CDATA[
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;
}
this._id("index-status-label").value = Zotero.getString('fulltext.indexState.indexed') + ':';
indexStatus.value = Zotero.getString(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.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"/>
<label id="url" crop="end"
ondragstart="var dt = event.dataTransfer; dt.setData('text/x-moz-url', this.value); dt.setData('text/uri-list', this.value); dt.setData('text/plain', this.value);"/>
<grid>
<columns>
<column/>
<column flex="1"/>
</columns>
<rows>
<row id="fileNameRow">
<label id="fileName-label"/>
<label id="fileName" crop="end"/>
</row>
<row id="accessedRow">
<label id="accessed-label"/>
<label id="accessed"/>
</row>
<row id="pagesRow">
<label id="pages-label"/>
<label id="pages"/>
</row>
<row id="dateModifiedRow">
<label id="dateModified-label"/>
<label id="dateModified"/>
</row>
<row id="indexStatusRow">
<label id="index-status-label"/>
<hbox>
<label id="index-status"/>
<toolbarbutton id="reindex" oncommand="this.hidden = true; setTimeout(function () { ZoteroPane_Local.reindexItem(); }, 50)"/>
</hbox>
</row>
</rows>
</grid>
<zoteronoteeditor id="note-editor" notitle="1" flex="1"/>
<button id="select-button" hidden="true"/>
</vbox>
</content>
</binding>
</bindings>