Close #1053, Manual sync option in library context menu
This also reworks how the collection context menu is built to do more in JS instead of XUL, though it can't do it all in JS because some localized strings are in zotero.dtd and are used in standalone.xul too.
This commit is contained in:
parent
893b9ae1fc
commit
fc857dc496
3 changed files with 226 additions and 113 deletions
|
@ -2313,7 +2313,111 @@ var ZoteroPane = new function()
|
|||
|
||||
|
||||
this.buildCollectionContextMenu = function (noRepeat) {
|
||||
var libraryID = this.getSelectedLibraryID();
|
||||
|
||||
// menuitem configuration
|
||||
//
|
||||
// This has to be kept in sync with zotero-collectionmenu in zoteroPane.xul. We could do this
|
||||
// entirely in JS, but various localized strings are only in zotero.dtd, and they're used in
|
||||
// standalone.xul as well, so for now they have to remain as XML entities.
|
||||
var options = [
|
||||
{
|
||||
id: "sync",
|
||||
label: Zotero.getString('sync.sync'),
|
||||
onclick: () => {
|
||||
Zotero.Sync.Runner.sync({
|
||||
libraries: [libraryID],
|
||||
});
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "sep1",
|
||||
},
|
||||
{
|
||||
id: "newCollection",
|
||||
command: "cmd_zotero_newCollection"
|
||||
},
|
||||
{
|
||||
id: "newSavedSearch",
|
||||
command: "cmd_zotero_newSavedSearch"
|
||||
},
|
||||
{
|
||||
id: "newSubcollection",
|
||||
onclick: () => {
|
||||
this.newCollection(this.getSelectedCollection().key);
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "refreshFeed",
|
||||
onclick: () => this.refreshFeed()
|
||||
},
|
||||
{
|
||||
id: "sep2",
|
||||
},
|
||||
{
|
||||
id: "showDuplicates",
|
||||
onclick: () => {
|
||||
this.setVirtual(libraryID, 'duplicates', true);
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "showUnfiled",
|
||||
onclick: () => {
|
||||
this.setVirtual(libraryID, 'unfiled', true);
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "editSelectedCollection",
|
||||
onclick: () => this.editSelectedCollection()
|
||||
},
|
||||
{
|
||||
id: "markReadFeed",
|
||||
onclick: () => this.markFeedRead()
|
||||
},
|
||||
{
|
||||
id: "editSelectedFeed",
|
||||
onclick: () => this.editSelectedFeed()
|
||||
},
|
||||
{
|
||||
id: "deleteCollection",
|
||||
onclick: () => this.deleteSelectedCollection()
|
||||
},
|
||||
{
|
||||
id: "deleteCollectionAndItems",
|
||||
onclick: () => this.deleteSelectedCollection(true)
|
||||
},
|
||||
{
|
||||
id: "sep3",
|
||||
},
|
||||
{
|
||||
id: "exportCollection",
|
||||
onclick: () => Zotero_File_Interface.exportCollection()
|
||||
},
|
||||
{
|
||||
id: "createBibCollection",
|
||||
onclick: () => Zotero_File_Interface.bibliographyFromCollection()
|
||||
},
|
||||
{
|
||||
id: "exportFile",
|
||||
onclick: () => Zotero_File_Interface.exportFile()
|
||||
},
|
||||
{
|
||||
id: "loadReport",
|
||||
onclick: event => Zotero_Report_Interface.loadCollectionReport(event)
|
||||
},
|
||||
{
|
||||
id: "emptyTrash",
|
||||
onclick: () => this.emptyTrash()
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
var collectionTreeRow = this.collectionsView.selectedTreeRow;
|
||||
// This can happen if selection is changing during delayed second call below
|
||||
if (!collectionTreeRow) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the items view isn't initialized, this was a right-click on a different collection and
|
||||
// the new collection's items are still loading, so update the menu after loading. This causes
|
||||
// some menu items (e.g., export/createBib/loadReport) to appear gray in the menu at first and
|
||||
|
@ -2324,169 +2428,174 @@ var ZoteroPane = new function()
|
|||
}.bind(this));
|
||||
}
|
||||
|
||||
var options = [
|
||||
"newCollection",
|
||||
"newSavedSearch",
|
||||
"newSubcollection",
|
||||
"refreshFeed",
|
||||
"sep1",
|
||||
"showDuplicates",
|
||||
"showUnfiled",
|
||||
"editSelectedCollection",
|
||||
"markReadFeed",
|
||||
"editSelectedFeed",
|
||||
"deleteCollection",
|
||||
"deleteCollectionAndItems",
|
||||
"sep2",
|
||||
"exportCollection",
|
||||
"createBibCollection",
|
||||
"exportFile",
|
||||
"loadReport",
|
||||
"emptyTrash",
|
||||
"createCommonsBucket",
|
||||
"refreshCommonsBucket"
|
||||
];
|
||||
|
||||
// Set attributes on the menu from the configuration object
|
||||
var menu = document.getElementById('zotero-collectionmenu');
|
||||
var m = {};
|
||||
for (let i = 0; i < options.length; i++) {
|
||||
m[options[i]] = i;
|
||||
let option = options[i];
|
||||
let menuitem = menu.childNodes[i];
|
||||
m[option.id] = menuitem;
|
||||
|
||||
menuitem.id = option.id;
|
||||
if (!menuitem.classList.contains('menuitem-iconic')) {
|
||||
menuitem.classList.add('menuitem-iconic');
|
||||
}
|
||||
if (option.label) {
|
||||
menuitem.setAttribute('label', option.label);
|
||||
}
|
||||
if (option.command) {
|
||||
menuitem.setAttribute('command', option.command);
|
||||
}
|
||||
else if (option.onclick) {
|
||||
menuitem.onclick = option.onclick;
|
||||
}
|
||||
}
|
||||
|
||||
var menu = document.getElementById('zotero-collectionmenu');
|
||||
|
||||
// By default things are hidden and visible, so we only need to record
|
||||
// when things are visible and when they're visible but disabled
|
||||
var show = [], disable = [];
|
||||
|
||||
if (collectionTreeRow.isCollection()) {
|
||||
show = [
|
||||
m.newSubcollection,
|
||||
m.sep1,
|
||||
m.editSelectedCollection,
|
||||
m.deleteCollection,
|
||||
m.deleteCollectionAndItems,
|
||||
m.sep2,
|
||||
m.exportCollection,
|
||||
m.createBibCollection,
|
||||
m.loadReport
|
||||
'newSubcollection',
|
||||
'sep2',
|
||||
'editSelectedCollection',
|
||||
'deleteCollection',
|
||||
'deleteCollectionAndItems',
|
||||
'sep3',
|
||||
'exportCollection',
|
||||
'createBibCollection',
|
||||
'loadReport'
|
||||
];
|
||||
var s = [m.exportCollection, m.createBibCollection, m.loadReport];
|
||||
|
||||
if (!this.itemsView.rowCount) {
|
||||
disable = s;
|
||||
disable = ['exportCollection', 'createBibCollection', 'loadReport'];
|
||||
}
|
||||
|
||||
// Adjust labels
|
||||
menu.childNodes[m.editSelectedCollection].setAttribute('label', Zotero.getString('pane.collections.menu.rename.collection'));
|
||||
menu.childNodes[m.deleteCollection].setAttribute('label', Zotero.getString('pane.collections.menu.delete.collection'));
|
||||
menu.childNodes[m.deleteCollectionAndItems].setAttribute('label', Zotero.getString('pane.collections.menu.delete.collectionAndItems'));
|
||||
menu.childNodes[m.exportCollection].setAttribute('label', Zotero.getString('pane.collections.menu.export.collection'));
|
||||
menu.childNodes[m.createBibCollection].setAttribute('label', Zotero.getString('pane.collections.menu.createBib.collection'));
|
||||
menu.childNodes[m.loadReport].setAttribute('label', Zotero.getString('pane.collections.menu.generateReport.collection'));
|
||||
m.editSelectedCollection.setAttribute('label', Zotero.getString('pane.collections.menu.rename.collection'));
|
||||
m.deleteCollection.setAttribute('label', Zotero.getString('pane.collections.menu.delete.collection'));
|
||||
m.deleteCollectionAndItems.setAttribute('label', Zotero.getString('pane.collections.menu.delete.collectionAndItems'));
|
||||
m.exportCollection.setAttribute('label', Zotero.getString('pane.collections.menu.export.collection'));
|
||||
m.createBibCollection.setAttribute('label', Zotero.getString('pane.collections.menu.createBib.collection'));
|
||||
m.loadReport.setAttribute('label', Zotero.getString('pane.collections.menu.generateReport.collection'));
|
||||
}
|
||||
else if (collectionTreeRow.isFeed()) {
|
||||
show = [
|
||||
m.refreshFeed,
|
||||
m.sep1,
|
||||
m.markReadFeed,
|
||||
m.editSelectedFeed,
|
||||
m.deleteCollectionAndItems
|
||||
'refreshFeed',
|
||||
'sep2',
|
||||
'markReadFeed',
|
||||
'editSelectedFeed',
|
||||
'deleteCollectionAndItems'
|
||||
];
|
||||
|
||||
if (collectionTreeRow.ref.unreadCount == 0) {
|
||||
disable.push(m.markReadFeed);
|
||||
disable = ['markReadFeed'];
|
||||
}
|
||||
|
||||
// Adjust labels
|
||||
menu.childNodes[m.deleteCollectionAndItems].setAttribute('label', Zotero.getString('pane.collections.menu.delete.feedAndItems'));
|
||||
m.deleteCollectionAndItems.setAttribute('label', Zotero.getString('pane.collections.menu.delete.feedAndItems'));
|
||||
}
|
||||
else if (collectionTreeRow.isSearch()) {
|
||||
show = [
|
||||
m.editSelectedCollection,
|
||||
m.deleteCollection,
|
||||
m.sep2,
|
||||
m.exportCollection,
|
||||
m.createBibCollection,
|
||||
m.loadReport
|
||||
'editSelectedCollection',
|
||||
'deleteCollection',
|
||||
'sep3',
|
||||
'exportCollection',
|
||||
'createBibCollection',
|
||||
'loadReport'
|
||||
];
|
||||
|
||||
menu.childNodes[m.deleteCollection].setAttribute('label', Zotero.getString('pane.collections.menu.delete.savedSearch'));
|
||||
m.deleteCollection.setAttribute('label', Zotero.getString('pane.collections.menu.delete.savedSearch'));
|
||||
|
||||
var s = [m.exportCollection, m.createBibCollection, m.loadReport];
|
||||
if (!this.itemsView.rowCount) {
|
||||
disable = s;
|
||||
disable.push('exportCollection', 'createBibCollection', 'loadReport');
|
||||
}
|
||||
|
||||
// Adjust labels
|
||||
menu.childNodes[m.editSelectedCollection].setAttribute('label', Zotero.getString('pane.collections.menu.edit.savedSearch'));
|
||||
menu.childNodes[m.exportCollection].setAttribute('label', Zotero.getString('pane.collections.menu.export.savedSearch'));
|
||||
menu.childNodes[m.createBibCollection].setAttribute('label', Zotero.getString('pane.collections.menu.createBib.savedSearch'));
|
||||
menu.childNodes[m.loadReport].setAttribute('label', Zotero.getString('pane.collections.menu.generateReport.savedSearch'));
|
||||
m.editSelectedCollection.setAttribute('label', Zotero.getString('pane.collections.menu.edit.savedSearch'));
|
||||
m.exportCollection.setAttribute('label', Zotero.getString('pane.collections.menu.export.savedSearch'));
|
||||
m.createBibCollection.setAttribute('label', Zotero.getString('pane.collections.menu.createBib.savedSearch'));
|
||||
m.loadReport.setAttribute('label', Zotero.getString('pane.collections.menu.generateReport.savedSearch'));
|
||||
}
|
||||
else if (collectionTreeRow.isTrash()) {
|
||||
show = [m.emptyTrash];
|
||||
show = ['emptyTrash'];
|
||||
}
|
||||
else if (collectionTreeRow.isDuplicates() || collectionTreeRow.isUnfiled()) {
|
||||
show = [
|
||||
m.deleteCollection
|
||||
];
|
||||
show = ['deleteCollection'];
|
||||
|
||||
menu.childNodes[m.deleteCollection].setAttribute('label', Zotero.getString('general.hide'));
|
||||
m.deleteCollection.setAttribute('label', Zotero.getString('general.hide'));
|
||||
}
|
||||
else if (collectionTreeRow.isHeader()) {
|
||||
if (collectionTreeRow.ref.id == 'commons-header') {
|
||||
show = [m.createCommonsBucket];
|
||||
}
|
||||
}
|
||||
else if (collectionTreeRow.isBucket()) {
|
||||
show = [m.refreshCommonsBucket];
|
||||
}
|
||||
else if (collectionTreeRow.isPublications()) {
|
||||
show = [m.exportFile];
|
||||
show = [
|
||||
'sync',
|
||||
'sep1',
|
||||
'exportFile'
|
||||
];
|
||||
}
|
||||
// Library
|
||||
else {
|
||||
show = [
|
||||
m.newCollection,
|
||||
m.newSavedSearch,
|
||||
m.sep1,
|
||||
m.showDuplicates,
|
||||
m.showUnfiled,
|
||||
m.sep2,
|
||||
m.exportFile
|
||||
'sync',
|
||||
'sep1',
|
||||
'newCollection',
|
||||
'newSavedSearch',
|
||||
];
|
||||
// Only show "Show Duplicates" and "Show Unfiled Items" if rows are hidden
|
||||
let duplicates = Zotero.Utilities.Internal.getVirtualCollectionStateForLibrary(
|
||||
libraryID, 'duplicates'
|
||||
);
|
||||
let unfiled = Zotero.Utilities.Internal.getVirtualCollectionStateForLibrary(
|
||||
libraryID, 'unfiled'
|
||||
);
|
||||
if (!duplicates || !unfiled) {
|
||||
show.push('sep2');
|
||||
if (!duplicates) {
|
||||
show.push('showDuplicates');
|
||||
}
|
||||
if (!unfiled) {
|
||||
show.push('showUnfiled');
|
||||
}
|
||||
}
|
||||
show.push(
|
||||
'sep3',
|
||||
'exportFile'
|
||||
);
|
||||
}
|
||||
|
||||
// Disable some actions if user doesn't have write access
|
||||
//
|
||||
// Some actions are disabled via their commands in onCollectionSelected()
|
||||
var s = [m.newSubcollection, m.editSelectedCollection, m.deleteCollection, m.deleteCollectionAndItems];
|
||||
if (collectionTreeRow.isWithinGroup() && !collectionTreeRow.editable && !collectionTreeRow.isDuplicates() && !collectionTreeRow.isUnfiled()) {
|
||||
disable = disable.concat(s);
|
||||
disable.push(
|
||||
'newSubcollection',
|
||||
'editSelectedCollection',
|
||||
'deleteCollection',
|
||||
'deleteCollectionAndItems'
|
||||
);
|
||||
}
|
||||
|
||||
// If within non-editable group or trash it empty, disable Empty Trash
|
||||
if (collectionTreeRow.isTrash()) {
|
||||
if ((collectionTreeRow.isWithinGroup() && !collectionTreeRow.isWithinEditableGroup()) || !this.itemsView.rowCount) {
|
||||
disable.push(m.emptyTrash);
|
||||
disable.push('emptyTrash');
|
||||
}
|
||||
}
|
||||
|
||||
// Hide and enable all actions by default (so if they're shown they're enabled)
|
||||
for (let i in m) {
|
||||
let pos = m[i];
|
||||
menu.childNodes[pos].setAttribute('hidden', true);
|
||||
menu.childNodes[pos].setAttribute('disabled', false);
|
||||
m[i].setAttribute('hidden', true);
|
||||
m[i].setAttribute('disabled', false);
|
||||
}
|
||||
|
||||
for (var i in show)
|
||||
{
|
||||
menu.childNodes[show[i]].setAttribute('hidden', false);
|
||||
for (let id of show) {
|
||||
m[id].setAttribute('hidden', false);
|
||||
}
|
||||
|
||||
for (var i in disable)
|
||||
{
|
||||
menu.childNodes[disable[i]].setAttribute('disabled', true);
|
||||
for (let id of disable) {
|
||||
m[id].setAttribute('disabled', true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -256,27 +256,27 @@
|
|||
|
||||
<popupset>
|
||||
<menupopup id="zotero-collectionmenu" onpopupshowing="ZoteroPane_Local.buildCollectionContextMenu();">
|
||||
<!-- Keep order in sync with buildCollectionContextMenu -->
|
||||
<menuitem class="menuitem-iconic zotero-menuitem-new-collection" label="&zotero.toolbar.newCollection.label;" command="cmd_zotero_newCollection"/>
|
||||
<menuitem class="menuitem-iconic zotero-menuitem-new-saved-search" label="&zotero.toolbar.newSavedSearch.label;" command="cmd_zotero_newSavedSearch"/>
|
||||
<menuitem class="menuitem-iconic zotero-menuitem-new-collection" label="&zotero.toolbar.newSubcollection.label;" oncommand="ZoteroPane_Local.newCollection(ZoteroPane_Local.getSelectedCollection().key)"/>
|
||||
<menuitem class="menuitem-iconic zotero-menuitem-refresh-feed" label="&zotero.toolbar.feeds.refresh;" oncommand="ZoteroPane_Local.refreshFeed();"/>
|
||||
<!-- Keep order in sync with buildCollectionContextMenu, which adds additional attributes -->
|
||||
<menuitem class="zotero-menuitem-sync"/>
|
||||
<menuseparator/>
|
||||
<menuitem class="menuitem-iconic zotero-menuitem-show-duplicates" label="&zotero.toolbar.duplicate.label;" oncommand="ZoteroPane_Local.setVirtual(ZoteroPane_Local.getSelectedLibraryID(), 'duplicates', true)"/>
|
||||
<menuitem class="menuitem-iconic zotero-menuitem-show-unfiled" label="&zotero.collections.showUnfiledItems;" oncommand="ZoteroPane_Local.setVirtual(ZoteroPane_Local.getSelectedLibraryID(), 'unfiled', true)"/>
|
||||
<menuitem class="menuitem-iconic zotero-menuitem-edit-collection" oncommand="ZoteroPane_Local.editSelectedCollection();"/>
|
||||
<menuitem class="menuitem-iconic zotero-menuitem-mark-read-feed" label="&zotero.toolbar.markFeedRead.label;" oncommand="ZoteroPane_Local.markFeedRead();"/>
|
||||
<menuitem class="menuitem-iconic zotero-menuitem-edit-feed" label="&zotero.toolbar.feeds.edit;" oncommand="ZoteroPane_Local.editSelectedFeed();"/>
|
||||
<menuitem class="menuitem-iconic zotero-menuitem-delete-collection" oncommand="ZoteroPane_Local.deleteSelectedCollection();"/>
|
||||
<menuitem class="menuitem-iconic zotero-menuitem-move-to-trash" oncommand="ZoteroPane_Local.deleteSelectedCollection(true);"/>
|
||||
<menuitem class="zotero-menuitem-new-collection" label="&zotero.toolbar.newCollection.label;"/>
|
||||
<menuitem class="zotero-menuitem-new-saved-search" label="&zotero.toolbar.newSavedSearch.label;"/>
|
||||
<menuitem class="zotero-menuitem-new-collection" label="&zotero.toolbar.newSubcollection.label;"/>
|
||||
<menuitem class="zotero-menuitem-refresh-feed" label="&zotero.toolbar.feeds.refresh;"/>
|
||||
<menuseparator/>
|
||||
<menuitem class="menuitem-iconic zotero-menuitem-export" oncommand="Zotero_File_Interface.exportCollection();"/>
|
||||
<menuitem class="menuitem-iconic zotero-menuitem-create-bibliography" oncommand="Zotero_File_Interface.bibliographyFromCollection();"/>
|
||||
<menuitem class="menuitem-iconic zotero-menuitem-export" label="&zotero.toolbar.export.label;" oncommand="Zotero_File_Interface.exportFile()"/>
|
||||
<menuitem class="menuitem-iconic zotero-menuitem-create-report" oncommand="Zotero_Report_Interface.loadCollectionReport(event)"/>
|
||||
<menuitem class="menuitem-iconic zotero-menuitem-delete-from-lib" label="&zotero.toolbar.emptyTrash.label;" oncommand="ZoteroPane_Local.emptyTrash();"/>
|
||||
<menuitem label="&zotero.toolbar.newCollection.label;" oncommand="ZoteroPane_Local.createCommonsBucket();"/><!--TODO localize -->
|
||||
<menuitem label="Refresh" oncommand="ZoteroPane_Local.refreshCommonsBucket();"/><!--TODO localize -->
|
||||
<menuitem class="zotero-menuitem-show-duplicates" label="&zotero.toolbar.duplicate.label;"/>
|
||||
<menuitem class="zotero-menuitem-show-unfiled" label="&zotero.collections.showUnfiledItems;"/>
|
||||
<menuitem class="zotero-menuitem-edit-collection"/>
|
||||
<menuitem class="zotero-menuitem-mark-read-feed" label="&zotero.toolbar.markFeedRead.label;"/>
|
||||
<menuitem class="zotero-menuitem-edit-feed" label="&zotero.toolbar.feeds.edit;"/>
|
||||
<menuitem class="zotero-menuitem-delete-collection"/>
|
||||
<menuitem class="zotero-menuitem-move-to-trash"/>
|
||||
<menuseparator/>
|
||||
<menuitem class="zotero-menuitem-export"/>
|
||||
<menuitem class="zotero-menuitem-create-bibliography"/>
|
||||
<menuitem class="zotero-menuitem-export" label="&zotero.toolbar.export.label;"/>
|
||||
<menuitem class="zotero-menuitem-create-report"/>
|
||||
<menuitem class="zotero-menuitem-delete-from-lib" label="&zotero.toolbar.emptyTrash.label;"/>
|
||||
</menupopup>
|
||||
<menupopup id="zotero-itemmenu">
|
||||
<!-- Keep order in sync with buildItemContextMenu -->
|
||||
|
|
|
@ -397,6 +397,10 @@
|
|||
list-style-image: url('chrome://zotero/skin/treesource-unfiled.png');
|
||||
}
|
||||
|
||||
.zotero-menuitem-sync {
|
||||
list-style-image: url(chrome://zotero/skin/arrow_rotate_static.png);
|
||||
}
|
||||
|
||||
.zotero-menuitem-new-collection
|
||||
{
|
||||
list-style-image: url('chrome://zotero/skin/toolbar-collection-add.png');
|
||||
|
|
Loading…
Reference in a new issue