Implemented egw_action shortcuts

This commit is contained in:
Andreas Stöckel 2011-06-19 10:48:51 +00:00
parent 40dd19fd3e
commit bf8437551d
6 changed files with 223 additions and 59 deletions

View File

@ -1162,57 +1162,61 @@ egwActionObject.prototype.handleKeyPress = function(_keyCode, _shift, _ctrl, _al
case EGW_KEY_ARROW_DOWN: case EGW_KEY_ARROW_DOWN:
case EGW_KEY_PAGE_UP: case EGW_KEY_PAGE_UP:
case EGW_KEY_PAGE_DOWN: case EGW_KEY_PAGE_DOWN:
var intval =
(_keyCode == EGW_KEY_ARROW_UP || _keyCode == EGW_KEY_ARROW_DOWN) ?
1 : 10;
if (this.children.length > 0) if (!_shift && !_ctrl && !_alt)
{ {
// Get the focused object var intval =
var focused = this.getFocusedObject(); (_keyCode == EGW_KEY_ARROW_UP || _keyCode == EGW_KEY_ARROW_DOWN) ?
1 : 10;
// Determine the object which should get selected if (this.children.length > 0)
var selObj = null;
if (!focused)
{ {
selObj = this.children[0]; // Get the focused object
} var focused = this.getFocusedObject();
else
{
selObj = (_keyCode == EGW_KEY_ARROW_UP || _keyCode == EGW_KEY_PAGE_UP) ?
focused.getPrevious(intval) : focused.getNext(intval);
}
if (selObj != null) // Determine the object which should get selected
{ var selObj = null;
if (!_shift) if (!focused)
{ {
this.setAllSelected(false); selObj = this.children[0];
} }
else else
{ {
var objs = focused.traversePath(selObj); selObj = (_keyCode == EGW_KEY_ARROW_UP || _keyCode == EGW_KEY_PAGE_UP) ?
for (var i = 0; i < objs.length; i++) focused.getPrevious(intval) : focused.getNext(intval);
{
objs[i].setSelected(true);
}
} }
selObj.setSelected(true); if (selObj != null)
selObj.setFocused(true); {
if (!_shift)
{
this.setAllSelected(false);
}
else
{
var objs = focused.traversePath(selObj);
for (var i = 0; i < objs.length; i++)
{
objs[i].setSelected(true);
}
}
// Tell the aoi of the object to make it visible selObj.setSelected(true);
selObj.makeVisible(); selObj.setFocused(true);
// Tell the aoi of the object to make it visible
selObj.makeVisible();
}
return true;
} }
return true;
} }
break; break;
// Handle CTRL-A to select all elements in the current container // Handle CTRL-A to select all elements in the current container
case EGW_KEY_A: case EGW_KEY_A:
if (_ctrl) if (_ctrl && !_shift && !_alt)
{ {
this.toggleAllSelected(); this.toggleAllSelected();
return true; return true;

View File

@ -62,27 +62,34 @@ function egwPopupAction(_id, _handler, _caption, _icon, _onExecute, _allowOnMult
} }
action.set_shortcut = function(_value) { action.set_shortcut = function(_value) {
var sc = { if (_value)
"keyCode": -1,
"shift": false,
"ctrl": false,
"alt": false
}
if (typeof _value == "number")
{ {
sc.keyCode = _value; var sc = {
} "keyCode": -1,
"shift": false,
"ctrl": false,
"alt": false
}
if (typeof _value == "object" && _value.keyCode != "undefined") if (typeof _value == "number")
{
sc.keyCode = _value;
}
if (typeof _value == "object" && _value.keyCode != "undefined")
{
sc.keyCode = _value.keyCode;
sc.shift = (typeof _value.shift == "undefined") ? false : _value.shift;
sc.ctrl = (typeof _value.ctrl == "undefined") ? false : _value.ctrl;
sc.alt = (typeof _value.alt == "undefined") ? false : _value.alt;
}
this.shortcut = sc;
}
else
{ {
sc.keyCode = _value.keyCode; this.shortcut = false;
sc.shift = (typeof _value.shift == "undefined") ? false : _value.shift;
sc.ctrl = (typeof _value.ctrl == "undefined") ? false : _value.ctrl;
sc.alt = (typeof _value.shift == "undefined") ? false : _value.alt;
} }
this.shortcut = null;
} }
return action; return action;
@ -147,18 +154,61 @@ function egwPopupActionImplementation()
return defaultAction; return defaultAction;
} }
ai._searchShortcut = function (_key, _objs, _links) {
for (var i = 0; i < _objs.length; i++)
{
var sc = _objs[i].shortcut;
if (sc && sc.keyCode == _key.keyCode && sc.shift == _key.shift &&
sc.ctrl == _key.ctrl && sc.alt == _key.alt &&
_objs[i].type == "popup" && (typeof _links[_objs[i].id] == "undefined" ||
_links[_objs[i].id].enabled))
{
return _objs[i];
}
var obj = this._searchShortcut(_key, _objs[i].children, _links);
if (obj) {
return obj;
}
}
}
ai._searchShortcutInLinks = function(_key, _links) {
var objs = [];
for (var k in _links)
{
if (_links[k].enabled)
{
objs.push(_links[k].actionObj);
}
}
return ai._searchShortcut(_key, objs, _links);
}
/** /**
* Handles a key press * Handles a key press
*/ */
ai._handleKeyPress = function(_key, _selected, _links, _target) { ai._handleKeyPress = function(_key, _selected, _links, _target) {
// Handle the default
if (_key.keyCode == EGW_KEY_ENTER && !_key.ctrl && !_key.shift && !_key.alt) { if (_key.keyCode == EGW_KEY_ENTER && !_key.ctrl && !_key.shift && !_key.alt) {
var defaultAction = this._getDefaultLink(_links); var defaultAction = this._getDefaultLink(_links);
if (defaultAction) if (defaultAction)
{ {
defaultAction.execute(_selected); defaultAction.execute(_selected);
return false; return true;
} }
} }
// Check whether the given shortcut exists
var obj = this._searchShortcutInLinks(_key, _links);
if (obj)
{
obj.execute(_selected);
return true;
}
return false;
} }
/** /**
@ -386,6 +436,13 @@ function egwPopupActionImplementation()
item.set_checkbox(link.actionObj.checkbox); item.set_checkbox(link.actionObj.checkbox);
item.set_checked(link.actionObj.checked); item.set_checked(link.actionObj.checked);
item.set_groupIndex(link.actionObj.radioGroup); item.set_groupIndex(link.actionObj.radioGroup);
if (link.actionObj.shortcut)
{
var sc = link.actionObj.shortcut;
item.set_shortcutCaption(egw_shortcutCaption(
sc.keyCode, sc.shift, sc.ctrl, sc.alt));
}
} }
item.set_data(link.actionObj); item.set_data(link.actionObj);

View File

@ -173,7 +173,94 @@ $(document).ready(function() {
}); });
/** /**
* Creates the shortcut structure * Default key tranlation table - do not override this variable when doing
* an translation, but set the EGW_LANG_KEYS assoc array!
*/
var _egw_lang_keys_default = {
"ctrl": "Ctrl",
"alt": "Alt",
"shift": "Shift"
}
_egw_lang_keys_default[EGW_KEY_DELETE] = "Del";
_egw_lang_keys_default[EGW_KEY_TAB] = "Tab";
_egw_lang_keys_default[EGW_KEY_ESCAPE] = "Esc";
_egw_lang_keys_default[EGW_KEY_BACKSPACE] = "Back";
_egw_lang_keys_default[EGW_KEY_PAGE_UP] = "Pg Up";
_egw_lang_keys_default[EGW_KEY_PAGE_DOWN] = "Pg Down";
_egw_lang_keys_default[EGW_KEY_ARROW_LEFT] = "Left";
_egw_lang_keys_default[EGW_KEY_ARROW_RIGHT] = "Right";
_egw_lang_keys_default[EGW_KEY_ARROW_DOWN] = "Down";
_egw_lang_keys_default[EGW_KEY_ARROW_UP] = "Up";
function egw_lang_keys_lookup(_keyCode) {
// Special keys - search for the key translation table - if not found,
// return default names
if (typeof EGW_LANG_KEYS != "undefined")
{
return EGW_LANG_KEYS[_keyCode];
}
return _egw_lang_keys_default[_keyCode];
}
/**
* Tranlates the given key into the an string
*/
function egw_keyName(_keyCode)
{
// Force the keyCode to be valid
_keyCode = egw_keycode_makeValid(_keyCode);
if (_keyCode == -1)
{
return "";
}
// Keys which can be directly translated into ASCII chars
if ((_keyCode >= EGW_KEY_0 && _keyCode <= EGW_KEY_9) ||
(_keyCode >= EGW_KEY_A && _keyCode <= EGW_KEY_Z))
{
return String.fromCharCode(_keyCode);
}
// Function keys
if (_keyCode >= EGW_KEY_F1 && _keyCode <= EGW_KEY_F12)
{
return "F" + (_keyCode - EGW_KEY_F1 + 1);
}
return egw_lang_keys_lookup(_keyCode);
}
/**
* Assembles the caption of a shortcut and returns it
*/
function egw_shortcutCaption(_keyCode, _shift, _ctrl, _alt)
{
var elems = [];
if (_shift)
{
elems.push(egw_lang_keys_lookup("shift"));
}
if (_ctrl)
{
elems.push(egw_lang_keys_lookup("ctrl"));
}
if (_alt)
{
elems.push(egw_lang_keys_lookup("alt"));
}
elems.push(egw_keyName(_keyCode));
return elems.join(" + ");
}
/**
* Creates an unique key for the given shortcut
*/ */
function egw_shortcutIdx(_keyCode, _shift, _ctrl, _alt) function egw_shortcutIdx(_keyCode, _shift, _ctrl, _alt)
{ {
@ -293,12 +380,15 @@ function egw_keyHandler(_keyCode, _shift, _ctrl, _alt) {
// Execute the egw_popup key handler of the focused object // Execute the egw_popup key handler of the focused object
if (!handled) { if (!handled) {
!focusedObject.executeActionImplementation({"keyEvent": { return focusedObject.executeActionImplementation(
"keyCode": _keyCode, {
"shift": _shift, "keyEvent": {
"ctrl": _ctrl, "keyCode": _keyCode,
"alt": _alt "shift": _shift,
}}, "popup", EGW_AO_EXEC_SELECTED); "ctrl": _ctrl,
"alt": _alt
}
}, "popup", EGW_AO_EXEC_SELECTED);
} }
return handled; return handled;

View File

@ -69,7 +69,8 @@ function _egwGenMenuStructure(_elements, _parent)
//TODO Implement menu item getters? //TODO Implement menu item getters?
if (key == "id" || key == "caption" || key == "iconUrl" || if (key == "id" || key == "caption" || key == "iconUrl" ||
key == "checkbox" || key == "checked" || key == "groupIndex" || key == "checkbox" || key == "checked" || key == "groupIndex" ||
key == "enabled" || key == "default" || key == "onClick") key == "enabled" || key == "default" || key == "onClick" ||
key == "hint" || key == "shortcutCaption")
{ {
item['set_' + key](obj[key]); item['set_' + key](obj[key]);
} }
@ -289,6 +290,7 @@ function egwMenuItem(_parent, _id)
this.onClick = null; this.onClick = null;
this["default"] = false; this["default"] = false;
this.data = null; this.data = null;
this.shortcutCaption = null;
this.children = []; this.children = [];
this.parent = _parent; this.parent = _parent;
@ -411,3 +413,8 @@ egwMenuItem.prototype.set_hint = function(_value)
this.hint = _value; this.hint = _value;
} }
egwMenuItem.prototype.set_shortcutCaption = function(_value)
{
this.shortcutCaption = _value;
}

View File

@ -126,6 +126,11 @@ egwMenuImpl.prototype._translateStructure = function(_structure, _parentId, _idC
elem.iconUrl, elem.iconUrl); elem.iconUrl, elem.iconUrl);
} }
if (elem.shortcutCaption != null)
{
this.dhtmlxmenu.setHotKey(id, elem.shortcutCaption);
}
if (elem.children.length > 0) if (elem.children.length > 0)
{ {
counter += this._translateStructure(elem.children, id, (_idCnt + counter)); counter += this._translateStructure(elem.children, id, (_idCnt + counter));

View File

@ -23,7 +23,8 @@ menu.loadStructure(
"id": "file_open", "id": "file_open",
"caption": "Open file...", "caption": "Open file...",
"iconUrl": "imgs/folder.png", "iconUrl": "imgs/folder.png",
"default": true "default": true,
"shortcutCaption": "CTRL + A"
}, },
{ {
"caption": "-" "caption": "-"