Don't show note in right-hand pane when editing in separate window

- When a child note is opened in a separate window, the parent window is
  selected. (This used to work but was broken in 5.0.)
- When a top-level note is opened (via double-click), the right-hand pane
  changes to show "Editing in separate window".
- If a note that's currently open in a separate window is clicked on,
  the right-hand pane shows "Editing in a separate window".
- If a note window is closed and the item is selected, the note editor
  reappears in the right-hand pane after the note is saved.

This will avoid unnecessary UI updates and data loss bugs from the two
notes getting out of sync (and is just generally cleaner).

Also:

- General cleanup of note display code
This commit is contained in:
Dan Stillman 2017-12-11 02:23:15 -05:00
parent b2c9a42103
commit dcfaa5521e
6 changed files with 126 additions and 83 deletions

View file

@ -222,6 +222,58 @@ var ZoteroItemPane = new function() {
});
this.onNoteSelected = function (item, editable) {
// If an external note window is open for this item, don't show the editor
if (ZoteroPane.findNoteWindow(item.id)) {
this.showNoteWindowMessage();
return;
}
var noteEditor = document.getElementById('zotero-note-editor');
noteEditor.mode = editable ? 'edit' : 'view';
noteEditor.parent = null;
noteEditor.item = item;
// 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
// undo content from another note into the current one.
var clearUndo = noteEditor.item ? noteEditor.item.id != item.id : false;
if (clearUndo) {
noteEditor.clearUndo();
}
document.getElementById('zotero-view-note-button').hidden = !editable;
document.getElementById('zotero-item-pane-content').selectedIndex = 2;
};
this.showNoteWindowMessage = function () {
ZoteroPane.setItemPaneMessage(Zotero.getString('pane.item.notes.editingInWindow'));
};
/**
* Select the parent item and open the note editor
*/
this.openNoteWindow = async function () {
var noteEditor = document.getElementById('zotero-note-editor');
var item = noteEditor.item;
// We don't want to show the note in two places, since it causes unnecessary UI updates
// and can result in weird bugs where note content gets lost.
//
// If this is a child note, select the parent
if (item.parentID) {
await ZoteroPane.selectItem(item.parentID);
}
// Otherwise, hide note and replace with a message that we're editing externally
else {
this.showNoteWindowMessage();
}
ZoteroPane.openNoteWindow(item.id);
};
this.addNote = function (popup) {
ZoteroPane_Local.newNote(popup, _lastItem.key);
}

View file

@ -114,7 +114,9 @@
<zoteronoteeditor id="zotero-note-editor" flex="1" notitle="1"
previousfocus="zotero-items-tree"
onerror="ZoteroPane.displayErrorMessage(); this.mode = 'view'"/>
<button id="zotero-view-note-button" label="&zotero.notes.separate;" oncommand="ZoteroPane_Local.openNoteWindow(this.getAttribute('noteID')); if(this.hasAttribute('sourceID')) ZoteroPane_Local.selectItem(this.getAttribute('sourceID'));"/>
<button id="zotero-view-note-button"
label="&zotero.notes.separate;"
oncommand="ZoteroItemPane.openNoteWindow()"/>
</groupbox>
<!-- Attachment item -->

View file

@ -26,7 +26,7 @@
var noteEditor;
var notifierUnregisterID;
function onLoad() {
async function onLoad() {
noteEditor = document.getElementById('zotero-note-editor');
noteEditor.mode = 'edit';
noteEditor.focus();
@ -37,13 +37,13 @@ function onLoad() {
if (window.arguments) {
var io = window.arguments[0];
}
var itemID = parseInt(io.itemID);
var collectionID = parseInt(io.collectionID);
var parentItemKey = io.parentItemKey;
return Zotero.spawn(function* () {
if (itemID) {
var ref = yield Zotero.Items.getAsync(itemID);
var ref = await Zotero.Items.getAsync(itemID);
var clearUndo = noteEditor.item ? noteEditor.item.id != ref.id : false;
@ -71,8 +71,7 @@ function onLoad() {
noteEditor.refresh();
}
notifierUnregisterID = Zotero.Notifier.registerObserver(NotifyCallback, 'item');
});
notifierUnregisterID = Zotero.Notifier.registerObserver(NotifyCallback, 'item', 'noteWindow');
}
// If there's an error saving a note, close the window and crash the app
@ -86,12 +85,13 @@ function onError() {
window.close();
}
function onUnload()
{
if(noteEditor && noteEditor.value)
noteEditor.save();
function onUnload() {
Zotero.Notifier.unregisterObserver(notifierUnregisterID);
if (noteEditor.item) {
window.opener.ZoteroPane.onNoteWindowClosed(noteEditor.item.id, noteEditor.value);
}
}
var NotifyCallback = {

View file

@ -15,7 +15,6 @@
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script src="include.js"/>
<script src="itemPane.js"/>
<script src="note.js"/>
<keyset>

View file

@ -53,7 +53,6 @@ var ZoteroPane = new function()
this.setItemsPaneMessage = setItemsPaneMessage;
this.clearItemsPaneMessage = clearItemsPaneMessage;
this.contextPopupShowing = contextPopupShowing;
this.openNoteWindow = openNoteWindow;
this.viewSelectedAttachment = viewSelectedAttachment;
this.reportErrors = reportErrors;
this.displayErrorMessage = displayErrorMessage;
@ -1479,37 +1478,7 @@ var ZoteroPane = new function()
var item = selectedItems[0];
if (item.isNote()) {
var noteEditor = document.getElementById('zotero-note-editor');
noteEditor.mode = this.collectionsView.editable ? 'edit' : 'view';
var clearUndo = noteEditor.item ? noteEditor.item.id != item.id : false;
noteEditor.parent = null;
noteEditor.item = item;
// 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
// undo content from another note into the current one.
if (clearUndo) {
noteEditor.clearUndo();
}
var viewButton = document.getElementById('zotero-view-note-button');
if (this.collectionsView.editable) {
viewButton.hidden = false;
viewButton.setAttribute('noteID', item.id);
if (!item.isTopLevelItem()) {
viewButton.setAttribute('parentItemID', item.parentItemID);
}
else {
viewButton.removeAttribute('parentItemID');
}
}
else {
viewButton.hidden = true;
}
document.getElementById('zotero-item-pane-content').selectedIndex = 2;
ZoteroItemPane.onNoteSelected(item, this.collectionsView.editable);
}
else if (item.isAttachment()) {
@ -3640,8 +3609,7 @@ var ZoteroPane = new function()
function openNoteWindow(itemID, col, parentKey)
{
this.openNoteWindow = function (itemID, col, parentKey) {
if (!this.canEdit()) {
this.displayCannotEditLibraryMessage();
return;
@ -3650,22 +3618,17 @@ var ZoteroPane = new function()
var name = null;
if (itemID) {
let w = this.findNoteWindow(itemID);
if (w) {
w.focus();
return;
}
// Create a name for this window so we can focus it later
//
// Collection is only used on new notes, so we don't need to
// include it in the name
name = 'zotero-note-' + itemID;
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
var e = wm.getEnumerator('zotero:note');
while (e.hasMoreElements()) {
var w = e.getNext();
if (w.name == name) {
w.focus();
return;
}
}
}
var io = { itemID: itemID, collectionID: col, parentItemKey: parentKey };
@ -3673,6 +3636,32 @@ var ZoteroPane = new function()
}
this.findNoteWindow = function (itemID) {
var name = 'zotero-note-' + itemID;
var wm = Services.wm;
var e = wm.getEnumerator('zotero:note');
while (e.hasMoreElements()) {
var w = e.getNext();
if (w.name == name) {
return w;
}
}
};
this.onNoteWindowClosed = async function (itemID, noteText) {
var item = Zotero.Items.get(itemID);
item.setNote(noteText);
await item.saveTx();
// If note is still selected, show the editor again when the note window closes
var selectedItems = this.getSelectedItems(true);
if (selectedItems.length == 1 && itemID == selectedItems[0]) {
ZoteroItemPane.onNoteSelected(item, this.collectionsView.editable);
}
};
this.addAttachmentFromURI = Zotero.Promise.method(function (link, itemID) {
if (!this.canEdit()) {
this.displayCannotEditLibraryMessage();

View file

@ -339,6 +339,7 @@ pane.item.notes.delete.confirm = Are you sure you want to delete this note?
pane.item.notes.count.zero = %S notes:
pane.item.notes.count.singular = %S note:
pane.item.notes.count.plural = %S notes:
pane.item.notes.editingInWindow = Editing in separate window
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.