From 2cce099928101ac43015e6c8ff51afc9aff4afdb Mon Sep 17 00:00:00 2001 From: Adomas Ven Date: Wed, 29 Jun 2016 03:12:54 +0300 Subject: [PATCH] Add custom view groups for different library types (#1042) I originally attempted this with zotero-persist and column attributes, but there is no good way to make it succinct paramswise and the code was painful to look at too. Thus different group settings are stored in preferences. Currently there are two view groups: "feed" and "default". Items view columns have two new attributes: `default-in` - a space separated list of views in which a column is visible by default `disabled-in` - a space separated list of views in which a column is disabled by default (invisible + not possible to enable) Fields not parsed for feeds are now disabled. --- .../content/zotero/xpcom/collectionTreeRow.js | 9 +++ chrome/content/zotero/xpcom/itemTreeView.js | 19 +++-- chrome/content/zotero/zoteroPane.js | 58 +++++++++------ chrome/content/zotero/zoteroPane.xul | 73 ++++++++++--------- test/tests/zoteroPaneTest.js | 43 +++++++++++ 5 files changed, 133 insertions(+), 69 deletions(-) diff --git a/chrome/content/zotero/xpcom/collectionTreeRow.js b/chrome/content/zotero/xpcom/collectionTreeRow.js index 02a0e7b9d1..e61ac30d03 100644 --- a/chrome/content/zotero/xpcom/collectionTreeRow.js +++ b/chrome/content/zotero/xpcom/collectionTreeRow.js @@ -194,6 +194,15 @@ Zotero.CollectionTreeRow.prototype.__defineGetter__('filesEditable', function () return false; }); + +Zotero.CollectionTreeRow.visibilityGroups = {'feed': 'feed'}; + + +Zotero.CollectionTreeRow.prototype.__defineGetter__('visibilityGroup', function() { + return Zotero.CollectionTreeRow.visibilityGroups[this.type] || 'default'; +}); + + Zotero.CollectionTreeRow.prototype.getName = function() { switch (this.type) { diff --git a/chrome/content/zotero/xpcom/itemTreeView.js b/chrome/content/zotero/xpcom/itemTreeView.js index 000ef5edf6..8c21aafbcd 100644 --- a/chrome/content/zotero/xpcom/itemTreeView.js +++ b/chrome/content/zotero/xpcom/itemTreeView.js @@ -2306,6 +2306,15 @@ Zotero.ItemTreeView.prototype.onColumnPickerShowing = function (event) { moreItems.push(elem); } } + + // Disable certain fields for feeds + let labels = Array.from(treecols.getElementsByAttribute('disabled-in', '*')) + .filter(e => e.getAttribute('disabled-in').split(' ').indexOf(this.collectionTreeRow.type) != -1) + .map(e => e.getAttribute('label')); + for (let i = 0; i < menupopup.childNodes.length; i++) { + let elem = menupopup.childNodes[i]; + elem.setAttribute('disabled', labels.indexOf(elem.getAttribute('label')) != -1); + } // Sort fields and move to submenu var collation = Zotero.getLocaleCollation(); @@ -2318,16 +2327,6 @@ Zotero.ItemTreeView.prototype.onColumnPickerShowing = function (event) { moreMenu.appendChild(moreMenuPopup); menupopup.insertBefore(moreMenu, lastChild); - - // Disable certain entries for feeds - let elems = Array.from(treecols.getElementsByAttribute('hidden-in', '*')) - let labels = Array.from(elems) - .filter(e => e.getAttribute('hidden-in').split(' ').indexOf(this.collectionTreeRow.type) != -1) - .map(e => e.getAttribute('label')); - for (let i = 0; i < menupopup.childNodes.length; i++) { - let elem = menupopup.childNodes[i]; - elem.setAttribute('disabled', labels.indexOf(elem.getAttribute('label')) != -1); - } } catch (e) { Components.utils.reportError(e); diff --git a/chrome/content/zotero/zoteroPane.js b/chrome/content/zotero/zoteroPane.js index 19c383278b..f3788786be 100644 --- a/chrome/content/zotero/zoteroPane.js +++ b/chrome/content/zotero/zoteroPane.js @@ -1243,39 +1243,51 @@ var ZoteroPane = new function() document.getElementById('zotero-items-tree').view = this.itemsView; try { + let tree = document.getElementById('zotero-items-tree'); let treecols = document.getElementById('zotero-items-columns-header'); let treecolpicker = treecols.boxObject.firstChild.nextSibling; let menupopup = treecolpicker.boxObject.firstChild.nextSibling; // Add events to treecolpicker to update menu before showing/hiding let attr = menupopup.getAttribute('onpopupshowing'); if (attr.indexOf('Zotero') == -1) { - menupopup.setAttribute('onpopupshowing', 'ZoteroPane.itemsView.onColumnPickerShowing(event);') + menupopup.setAttribute('onpopupshowing', 'ZoteroPane.itemsView.onColumnPickerShowing(event); ' // Keep whatever else is there - + ' ' + attr; - menupopup.setAttribute('onpopuphidden', 'ZoteroPane.itemsView.onColumnPickerHidden(event);') + + attr); + menupopup.setAttribute('onpopuphidden', 'ZoteroPane.itemsView.onColumnPickerHidden(event); ' // Keep whatever else is there - + ' ' + menupopup.getAttribute('onpopuphidden'); + + menupopup.getAttribute('onpopuphidden')); } - // Hide certain columns for feeds - let elems = treecols.getElementsByAttribute('hidden-in', '*'); - for (let i = 0; i < elems.length; i++) { - let shouldHide = elems[i].getAttribute('hidden-in').split(' ') - .indexOf(collectionTreeRow.type) != -1; - let userHidden = elems[i].hasAttribute('user-hidden'); - // The slightly convoluted logic here is such: - // If the current tree being displayed is in the list of types 'hidden-in' - // specifies and it's not already been hidden by another 'hidden-in' rule - // (i.e. its normal state of being displayed has not been suppressed yet), - // then hide it - if (shouldHide && !userHidden) { - // Store old value on entry to feed view - elems[i].setAttribute('user-hidden', elems[i].getAttribute('hidden')); - elems[i].setAttribute('hidden', 'true'); - } else if (!shouldHide && userHidden) { - // Restore old value on exit from feed view - elems[i].setAttribute('hidden', elems[i].getAttribute('user-hidden')); - elems[i].removeAttribute('user-hidden'); + // Items view column visibility for different groups + let prevViewGroup = tree.getAttribute('current-view-group'); + let curViewGroup = collectionTreeRow.visibilityGroup; + tree.setAttribute('current-view-group', curViewGroup); + if (curViewGroup != prevViewGroup) { + let cols = Array.from(treecols.getElementsByTagName('treecol')); + let settings = JSON.parse(Zotero.Prefs.get('itemsView.columnVisibility') || '{}'); + if (prevViewGroup) { + // Store previous view settings + let setting = {}; + for (let col of cols) { + let colType = col.id.substring('zotero-items-column-'.length); + setting[colType] = col.getAttribute('hidden') == 'true' ? 0 : 1 + } + settings[prevViewGroup] = setting; + Zotero.Prefs.set('itemsView.columnVisibility', JSON.stringify(settings)); + } + + // Recover current view settings + if (settings[curViewGroup]) { + for (let col of cols) { + let colType = col.id.substring('zotero-items-column-'.length); + col.setAttribute('hidden', !settings[curViewGroup][colType]); + } + } else { + cols.forEach((col) => { + col.setAttribute('hidden', !(col.hasAttribute('default-in') && + col.getAttribute('default-in').split(' ').indexOf(curViewGroup) != -1) + ) + }) } } } diff --git a/chrome/content/zotero/zoteroPane.xul b/chrome/content/zotero/zoteroPane.xul index 66dac60758..04910a22cc 100644 --- a/chrome/content/zotero/zoteroPane.xul +++ b/chrome/content/zotero/zoteroPane.xul @@ -370,186 +370,187 @@ onkeydown="ZoteroPane_Local.handleKeyDown(event, this.id)" onselect="ZoteroPane_Local.itemSelected(event)" oncommand="ZoteroPane_Local.serializePersist()" - flex="1"> + flex="1" + zotero-persist="current-view-group">