Closes #532, Highlight collections containing item(s) when pressing alt/option

Also:

- New method, Collections.getCollectionsContainingItems(itemIDs, asIDs)
- Convenience property Zotero.isWin
- ZoteroPane.onKeyUp()
This commit is contained in:
Dan Stillman 2007-02-06 09:08:06 +00:00
parent b4bdede0d1
commit 51e2d36dd1
6 changed files with 125 additions and 6 deletions

View File

@ -33,7 +33,9 @@ var ZoteroPane = new function()
this.onUnload = onUnload;
this.toggleDisplay = toggleDisplay;
this.fullScreen = fullScreen;
this.handleKeyPress = handleKeyPress;
this.handleKeyDown = handleKeyDown;
this.handleKeyUp = handleKeyUp;
this.setHighlightedRowsCallback = setHighlightedRowsCallback;
this.newItem = newItem;
this.newCollection = newCollection;
this.newSearch = newSearch;
@ -91,6 +93,9 @@ var ZoteroPane = new function()
newPane.setAttribute('id','zotero-pane');
newPane.setAttribute('persist','height');
newPane.setAttribute('hidden', true);
newPane.setAttribute('onkeydown', 'ZoteroPane.handleKeyDown(event, this.id)');
newPane.setAttribute('onkeyup', 'ZoteroPane.handleKeyUp(event, this.id)');
newPane.height = oldPane.height;
while(oldPane.hasChildNodes())
newPane.appendChild(oldPane.firstChild);
@ -214,7 +219,33 @@ var ZoteroPane = new function()
/*
* Trigger actions based on keyboard shortcuts
*/
function handleKeyPress(event) {
function handleKeyDown(event, from) {
if (from == 'zotero-pane') {
// Highlight collections containing selected items
//
// We use Control (17) on Windows because Alt triggers the menubar;
// otherwise we use Alt/Option (18)
if ((Zotero.isWin && event.keyCode == 17 && !event.altKey) ||
(!Zotero.isWin && event.keyCode == 18 && !event.ctrlKey)
&& !event.shiftKey && !event.metaKey) {
this.highlightTimer = Components.classes["@mozilla.org/timer;1"].
createInstance(Components.interfaces.nsITimer);
// {} implements nsITimerCallback
this.highlightTimer.initWithCallback({
notify: ZoteroPane.setHighlightedRowsCallback
}, 225, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
}
else if ((Zotero.isWin && event.ctrlKey) ||
(!Zotero.isWin && event.altKey)) {
if (this.highlightTimer) {
this.highlightTimer.cancel();
this.highlightTimer = null;
}
ZoteroPane.collectionsView.setHighlightedRows();
}
}
// Ignore keystrokes if Zotero pane is closed
if (document.getElementById('zotero-pane').getAttribute('hidden') == 'true') {
return;
@ -264,13 +295,42 @@ var ZoteroPane = new function()
ZoteroPane.fullScreen();
break;
default:
throw ('Command "' + command + '" not found in ZoteroPane.handleKeyPress()');
throw ('Command "' + command + '" not found in ZoteroPane.handleKeyDown()');
}
event.preventDefault();
}
function handleKeyUp(event, from) {
if (from == 'zotero-pane') {
if ((Zotero.isWin && event.keyCode == 17) ||
(!Zotero.isWin && event.keyCode == 18)) {
if (this.highlightTimer) {
this.highlightTimer.cancel();
this.highlightTimer = null;
}
ZoteroPane.collectionsView.setHighlightedRows();
}
}
}
/*
* Highlights collections containing selected items on Ctrl (Win) or
* Option/Alt (Mac/Linux) press
*/
function setHighlightedRowsCallback() {
var itemIDs = ZoteroPane.getSelectedItems(true);
if (itemIDs) {
var collectionIDs = Zotero.Collections.getCollectionsContainingItems(itemIDs, true);
if (collectionIDs) {
ZoteroPane.collectionsView.setHighlightedRows(collectionIDs);
}
}
}
/*
* Create a new item
*

View File

@ -66,7 +66,9 @@
<!-- onmouseup shouldn't be necessary but seems to help prevent tag selector from sometimes going off the screen -->
<splitter id="zotero-splitter" resizebefore="closest" resizeafter="closest" hidden="true"
onmouseup="ZoteroPane.updateTagSelectorSize()"/>
<hbox id="zotero-pane" persist="height" hidden="true">
<hbox id="zotero-pane" persist="height" hidden="true"
onkeydown="ZoteroPane.handleKeyDown(event, this.id)"
onkeyup="ZoteroPane.handleKeyUp(event, this.id)">
<popupset>
<popup id="zotero-collectionmenu" onpopupshowing="ZoteroPane.buildCollectionContextMenu();">
<menuitem label="&zotero.toolbar.newCollection.label;" oncommand="ZoteroPane.newCollection()"/>
@ -120,6 +122,7 @@
</toolbarbutton>
</toolbar>
<tree id="zotero-collections-tree" hidecolumnpicker="true" context="zotero-collectionmenu"
onmouseover="ZoteroPane.collectionsView.setHighlightedRows();"
ondblclick="ZoteroPane.onDoubleClick(event, this);"
onselect="ZoteroPane.onCollectionSelected();" seltype="single"
ondragdrop="nsDragAndDrop.drop(event, ZoteroPane.collectionsView)"
@ -339,7 +342,7 @@
}
}, false);
document.getElementById('appcontent').addEventListener('keydown', ZoteroPane.handleKeyPress, true);
document.getElementById('appcontent').addEventListener('keydown', ZoteroPane.handleKeyDown, true);
</script>
<menupopup id="menu_ToolsPopup">

View File

@ -36,6 +36,8 @@ Zotero.CollectionTreeView = function()
this._treebox = null;
this.refresh();
this._highlightedRows = {};
this._unregisterID = Zotero.Notifier.registerObserver(this, ['collection', 'search']);
}
@ -212,6 +214,22 @@ Zotero.CollectionTreeView.prototype.notify = function(action, type, ids)
}
}
/*
* Set the rows that should be highlighted -- actually highlighting is done
* by getRowProperties based on the array set here
*/
Zotero.CollectionTreeView.prototype.setHighlightedRows = function (ids) {
this._highlightedRows = {};
this._treebox.invalidate();
for each(var id in ids) {
this._highlightedRows[this._collectionRowMap[id]] = true;
this._treebox.invalidateRow(this._collectionRowMap[id]);
}
}
/*
* Unregisters view from Zotero.Notifier (called on window close)
*/
@ -634,7 +652,16 @@ Zotero.CollectionTreeView.prototype.onDrop = function (evt,dropdata,session) { }
Zotero.CollectionTreeView.prototype.isSorted = function() { return false; }
Zotero.CollectionTreeView.prototype.isSeparator = function(row) { return false; }
Zotero.CollectionTreeView.prototype.isEditable = function(row, idx) { return false; }
Zotero.CollectionTreeView.prototype.getRowProperties = function(row, prop) { }
/* Set 'highlighted' property on rows set by setHighlightedRows */
Zotero.CollectionTreeView.prototype.getRowProperties = function(row, props) {
if (this._highlightedRows[row]) {
var aServ = Components.classes["@mozilla.org/atom-service;1"].
getService(Components.interfaces.nsIAtomService);
props.AppendElement(aServ.getAtom("highlighted"));
}
}
Zotero.CollectionTreeView.prototype.getColumnProperties = function(col, prop) { }
Zotero.CollectionTreeView.prototype.getCellProperties = function(row, col, prop) { }
Zotero.CollectionTreeView.prototype.performAction = function(action) { }

View File

@ -3021,6 +3021,7 @@ Zotero.Collections = new function(){
this.get = get;
this.add = add;
this.getCollectionsContainingItems = getCollectionsContainingItems;
this.reloadAll = reloadAll;
this.unload = unload;
@ -3073,6 +3074,26 @@ Zotero.Collections = new function(){
}
function getCollectionsContainingItems(itemIDs, asIDs) {
var sql = "SELECT collectionID FROM collections WHERE ";
var sqlParams = [];
for each(var id in itemIDs) {
sql += "collectionID IN (SELECT collectionID FROM collectionItems "
+ "WHERE itemID=?) AND "
sqlParams.push(id);
}
sql = sql.substring(0, sql.length - 5);
var collectionIDs = Zotero.DB.columnQuery(sql, sqlParams);
if (asIDs) {
return collectionIDs;
}
return Zotero.Collections.get(collectionIDs);
}
/**
* Clear collection from internal cache (used by Zotero.Collection.erase())
*

View File

@ -65,6 +65,7 @@ var Zotero = new function(){
this.platform;
this.locale;
this.isMac;
this.isWin;
/*
* Initialize the extension
@ -106,6 +107,7 @@ var Zotero = new function(){
.hiddenDOMWindow;
this.platform = win.navigator.platform;
this.isMac = (this.platform.substr(0, 3) == "Mac");
this.isWin = (this.platform.substr(0, 3) == "Win");
// Locale
var localeService = Components.classes['@mozilla.org/intl/nslocaleservice;1'].

View File

@ -64,6 +64,12 @@
margin-right: 5px;
}
/* Set by setHighlightedRows() and getCellProperties() in collectionTreeView.js) */
#zotero-collections-tree treechildren::-moz-tree-row(highlighted)
{
background: #FFFF99;
}
#zotero-pane splitter
{