/* * #dependsFile client/zarafa/core/KeyMapMgr.js */ Ext.namespace('Zarafa.common'); /** * @class Zarafa.common.KeyMapping * @extends Object * * The map of keys used for global functionalities. * @singleton */ Zarafa.common.KeyMapping = Ext.extend(Object, { /** * @constructor */ constructor: function() { var numberKeys = [ // number keys from main keyboard Ext.EventObject.ZERO, Ext.EventObject.ONE, Ext.EventObject.TWO, Ext.EventObject.THREE, Ext.EventObject.FOUR, Ext.EventObject.FIVE, Ext.EventObject.SIX, Ext.EventObject.SEVEN, Ext.EventObject.EIGHT, Ext.EventObject.NINE, // number keys from numpad Ext.EventObject.NUM_ZERO, Ext.EventObject.NUM_ONE, Ext.EventObject.NUM_TWO, Ext.EventObject.NUM_THREE, Ext.EventObject.NUM_FOUR, Ext.EventObject.NUM_FIVE, Ext.EventObject.NUM_SIX, Ext.EventObject.NUM_SEVEN, Ext.EventObject.NUM_EIGHT, Ext.EventObject.NUM_NINE ]; var mainTabBar = [{ key: numberKeys, ctrl: true, alt: false, shift: false, // Overwrites the browser behavior to switch between tabs stopEvent: true, handler: this.onSwitchContexts, scope: this, settingsCfg : { description : _('Switch between different contexts e.g. inbox, calendar, etc.'), category : _('Basic navigation') } }]; var mainToolbarKeys = [{ key: numberKeys, ctrl: true, alt: true, shift: false, stopEvent: true, handler: this.onSwitchViews, scope: this, settingsCfg : { description : _('Switch between different views'), category : _('Basic navigation') } },{ key: Ext.EventObject.N, ctrl: true, alt: true, shift: false, stopEvent: true, handler: this.onNewItem, scope: this, settingsCfg : { description : _('New item'), category : _('Creating an item') } },{ key: Ext.EventObject.F5, ctrl: false, alt: false, shift: false, stopEvent: true, handler: this.onRefresh, scope: this, settingsCfg : { description : _('Refresh'), category : _('All views') }, basic: true }]; var contentPanelActionsKeys = [{ key: Ext.EventObject.W, ctrl: true, alt: true, shift: false, stopEvent: true, handler: this.onCloseCurrentMainContentTab, scope: this, settingsCfg : { description : _('Close tab'), category : _('Basic navigation') } }]; var defaultPrintMessageKey = [{ key: Ext.EventObject.P, ctrl: true, alt: false, shift: false, // Overwrites the browser behavior of opening print dialog stopEvent: true, handler: this.onPrintItem, scope: this, settingsCfg : { description : _('Print item'), category : _('Items') }, basic: true }]; var defaultRecordActionsKeys = [{ key: Ext.EventObject.S, ctrl: true, alt: false, shift: false, // Overwrites the browser behavior of opening save dialog stopEvent: true, handler: this.onSaveTabItem, scope: this, settingsCfg : { description : _('Save an item e.g. mail, contact, etc.'), category : _('Items') }, basic: true }]; var defaultMessageActionsKeys = [{ key: Ext.EventObject.ENTER, ctrl: true, alt: false, shift: false, stopEvent: true, handler: this.onSendTabItem, scope: this, settingsCfg : { description : _('Send an item e.g. mail, meeting request, etc.'), category : _('Items') }, basic: true }]; var selectionKey = [{ key: Ext.EventObject.A, ctrl: true, alt: false, shift: false, // Overwrites the browser behavior to select everything stopEvent: true, // enable this key combination globally because we will be having a different // key binding to disable ctrl + a in global scope enableGlobally : true, handler: this.onSelectAll, scope: this, settingsCfg : { description : _('Select all items'), category : _('All views') }, basic: true },{ key: Ext.EventObject.HOME, ctrl: false, alt: false, shift: true, handler: this.onSelectUpDown, scope: this, settingsCfg : { description : _('Extend the selection to the first item in the list'), category : _('All views') } },{ key: Ext.EventObject.END, ctrl: false, alt: false, shift: true, handler: this.onSelectUpDown, scope: this, settingsCfg : { description : _('Extend the selection to the last item in the list'), category : _('All views') } }]; var mapiMessageKeys = [{ key: Ext.EventObject.ENTER, ctrl: false, alt: false, shift: false, stopEvent: true, enableGlobally : true, handler: this.onOpenItem, scope: this, settingsCfg : { description : _('Open selected item'), category : _('All views') }, basic: true },{ key: Ext.EventObject.G, ctrl: true, alt: false, shift: false, stopEvent: true, handler: this.onCategorize, scope: this, settingsCfg : { description : _('Open dialog to categorize selected item'), category : _('All views') } },{ key: Ext.EventObject.P, ctrl: true, alt: true, shift: false, // Overwrites the browser behavior of opening print dialog stopEvent: true, handler: this.onPrintList, scope: this, settingsCfg : { description : _('Print list'), category : _('All views') } },{ key: Ext.EventObject.P, ctrl: true, alt: false, shift: false, // Overwrites the browser behavior of opening print dialog stopEvent: true, handler: this.onPrintListItem, scope: this, settingsCfg : { description : _('Print selected item'), category : _('All views') }, basic: true },{ key: Ext.EventObject.M, ctrl: true, alt: false, shift: false, stopEvent: true, handler: this.onMoveItem, scope: this, settingsCfg : { description : _('Open copy/move dialog'), category : _('All views') } },{ key: Ext.EventObject.DELETE, ctrl: false, alt: false, shift: false, stopEvent: true, enableGlobally : true, handler: this.onDeleteItem, scope: this, settingsCfg : { description : _('Delete selected item'), category : _('All views') }, basic: true },{ key: Ext.EventObject.DELETE, ctrl: false, alt: false, shift: true, stopEvent: true, enableGlobally : true, handler: this.onSoftDeleteItem, scope: this, settingsCfg : { description : _('Delete selected item without moving it to the Deleted Items folder. The deleted item can still be restored.'), category : _('All views') }, basic: true }]; var reminderKeys = [{ key: Ext.EventObject.ENTER, ctrl: false, alt: false, shift: false, stopEvent: true, enableGlobally: true, handler: this.onOpenReminder, scope: this // not specifying settingsCfg as we already have an entry of opening item in all views }]; Zarafa.core.KeyMapMgr.register('global', mainTabBar); Zarafa.core.KeyMapMgr.register('global', mainToolbarKeys); Zarafa.core.KeyMapMgr.register('grid', selectionKey); Zarafa.core.KeyMapMgr.register('view.mapimessage', selectionKey); Zarafa.core.KeyMapMgr.register('grid.mapimessage', mapiMessageKeys); Zarafa.core.KeyMapMgr.register('view.mapimessage', mapiMessageKeys); Zarafa.core.KeyMapMgr.register('grid.reminder', reminderKeys); Zarafa.core.KeyMapMgr.register('contentpanel', contentPanelActionsKeys); Zarafa.core.KeyMapMgr.register('contentpanel.record', defaultPrintMessageKey); Zarafa.core.KeyMapMgr.register('contentpanel.record', defaultRecordActionsKeys); Zarafa.core.KeyMapMgr.register('contentpanel.record.message', defaultMessageActionsKeys); Zarafa.core.KeyMapMgr.register('previewpanel.mail', defaultPrintMessageKey); }, /** * Event handler for the keydown event of the {@link Zarafa.core.KeyMap KeyMap} * when the user wants to create a new item. * @param {Number} key Key code * @param {Ext.EventObject} event The event * @param {Ext.Component} component The component on which key event is fired. */ onNewItem: function(key, event, component) { var newButton = container.getMainPanel().mainToolbar.newButton; newButton.handler.call(newButton.scope); }, /** * Event handler for the keydown event of the {@link Zarafa.core.KeyMap KeyMap} * when the user wants to refresh the view. * @param {Number} key Key code * @param {Ext.EventObject} event The event * @param {Ext.Component} component The component on which key event is fired. */ onRefresh: function(key, event, component) { var refreshButton = container.getMainPanel().mainToolbar.refreshButton; if(!refreshButton.isVisible()) { // don't call handler if button is hidden return; } refreshButton.handler.call(refreshButton.scope); }, /** * Event handler for the keydown event of the {@link Zarafa.core.KeyMap KeyMap} * when the user wants to switch between {@link Zarafa.core.Context Contexts}. * @param {Number} key Key code * @param {Ext.EventObject} event The event * @param {Ext.Component} component The component on which key event is fired. */ onSwitchContexts: function(key, event, component) { var itemNumber = parseInt(event.getKeyCharCode(), 10); var mainTabBar = container.getMainPanel().mainTabBar; var item, items = mainTabBar.find('type', 'button'); item = items[itemNumber]; if(item && item.handler && item.handler !== mainTabBar.onLogoutButton){ item.handler.call(item.scope || item); } }, /** * Event handler for the keydown event of the {@link Zarafa.core.KeyMap KeyMap} * when the user wants to switch between the available views. * @param {Number} key Key code * @param {Ext.EventObject} event The event * @param {Ext.Component} component The component on which key event is fired. */ onSwitchViews: function(key, event, component) { // Get key number which was pressed, we need to decrease it by one // as in views array we have first view saved at '0' index. var itemNumber = parseInt(event.getKeyCharCode(), 10) - 1; var activeContext = container.getCurrentContext(); // Get the view buttons directly from the Context var item, items = activeContext.getMainToolbarViewButtons(); item = items[itemNumber]; if(item && item.handler){ item.handler.call(item.scope || item, item); } }, /** * Event handler for the keydown event of the {@link Zarafa.core.KeyMap KeyMap} * when the user wants to close the current tab he has open in the * {@link Zarafa.core.ui.MainContentTabPanel MainContentTabPanel}. * @param {Number} key Key code * @param {Ext.EventObject} event The event * @param {Ext.Component} component The component on which key event is fired. */ onCloseCurrentMainContentTab: function(key, event, component) { if(component.closable) { component[component.closeAction](); } }, /** * Event handler for the keydown event of the {@link Zarafa.core.KeyMap KeyMap} * when the user wants to send the item that is open in the * {@link Zarafa.core.ui.MessageContentPanel MessageContentPanel}. * @param {Number} key Key code * @param {Ext.EventObject} event The event * @param {Ext.Component} component The component on which key event is fired. */ onSendTabItem: function(key, event, component) { if(Ext.isFunction(component.sendRecord)) { component.sendRecord(); } }, /** * Event handler for the keydown event of the {@link Zarafa.core.KeyMap KeyMap} * when the user wants to save the item that is open in the * {@link Zarafa.core.ui.RecordContentPanel RecordContentPanel}. * @param {Number} key Key code * @param {Ext.EventObject} event The event * @param {Ext.Component} component The component on which key event is fired. */ onSaveTabItem: function(key, event, component) { if(Ext.isFunction(component.saveRecord)) { component.saveRecord(); } }, /** * Event handler for the keydown event of the {@link Zarafa.core.KeyMap KeyMap} * when the user wants to print an item. * @param {Number} key Key code * @param {Ext.EventObject} event The event * @param {String} context The name of the context the key is pressed in * @param {Ext.Component} component The component on which key event is fired. */ onPrintItem: function(key, event, component) { if(component.record){ Zarafa.common.Actions.openPrintDialog(component.record); } }, /** * Event handler for the keydown event of the {@link Ext.KeyMap KeyMap} * when the user wants to print a list of items. * @param {Number} key Key code * @param {Ext.EventObject} event The event * @param {String} context The name of the context the key is pressed in * @param {Ext.Component} component The component on which key event is fired. */ onPrintList: function(key, event, component) { // Currently Print List functionality is only available with task, // In future, Print List will be implemented for all the Contexts. if (component.context) { Zarafa.common.Actions.openPrintDialog(component.context); } }, /** * Helper function to get selected records from component. * @param {Ext.Component} component The component on which key event is fired. * @return {Ext.data.Record[]} The records which are selected int the view. * @private */ getSelectedRecords : function (component) { if(Ext.isFunction(component.getSelectedRecords)) { return component.getSelectedRecords(); } else if(Ext.isFunction(component.getSelectionModel)) { return component.getSelectionModel().getSelections(); } return []; }, /** * Event handler for the keydown event of the {@link Zarafa.core.KeyMap KeyMap} * when the user wants to print selected item. * @param {Number} key Key code * @param {Ext.EventObject} event The event * @param {Ext.Component} component The component on which key event is fired. */ onPrintListItem: function(key, event, component) { var records = this.getSelectedRecords(component); if(!Ext.isEmpty(records)) { Zarafa.common.Actions.openPrintDialog(records); } }, /** * Event handler for the keydown event of the {@link Zarafa.core.KeyMap KeyMap} * when the user wants to move an item. * @param {Number} key Key code * @param {Ext.EventObject} event The event * @param {Ext.Component} component The component on which key event is fired. */ onMoveItem: function(key, event, component) { var records = this.getSelectedRecords(component); if(!Ext.isEmpty(records)) { Zarafa.common.Actions.openCopyMoveContent(records); } }, /** * Event handler for the keydown event of the {@link Zarafa.core.KeyMap KeyMap} * when the user wants to delete an item. * @param {Number} key Key code * @param {Ext.EventObject} event The event * @param {Ext.Component} component The component on which key event is fired. */ onDeleteItem: function(key, event, component) { var records = this.getSelectedRecords(component); if(!Ext.isEmpty(records)) { Zarafa.common.Actions.deleteRecords(records); } }, /** * Event handler for the keydown event of the {@link Zarafa.core.KeyMap KeyMap} * when the user wants to soft delete an item. * @param {Number} key Key code * @param {Ext.EventObject} event The event * @param {Ext.Component} component The component on which key event is fired. */ onSoftDeleteItem: function(key, event, component) { var records = this.getSelectedRecords(component); if(!Ext.isEmpty(records)) { Zarafa.common.Actions.deleteRecords(records, false, true); } }, /** * Event handler for the keydown event of the {@link Ext.KeyMap KeyMap} * when the user wants to categorize an item. * @param {Number} key Key code * @param {Ext.EventObject} event The event * @param {Ext.Component} component The component on which key event is fired. */ onCategorize: function(key, event, component) { var records = this.getSelectedRecords(component); if(!Ext.isEmpty(records)) { Zarafa.common.Actions.openCategoriesContent(records); } }, /** * Event handler for the keydown event of the {@link Ext.KeyMap KeyMap} * when the user wants to open an item. * @param {Number} key Key code * @param {Ext.EventObject} event The event * @param {Ext.Component} component The component on which key event is fired. */ onOpenItem: function(key, event, component) { var records = this.getSelectedRecords(component); if(!Ext.isEmpty(records)) { for(var i = 0, len = records.length; i < len; i++){ if(records[i].isUnsent() && !records[i].isFaultyMessage()) { Zarafa.core.data.UIFactory.openCreateRecord(records[i]); } else { Zarafa.core.data.UIFactory.openViewRecord(records[i]); } } } }, /** * Event handler for the keydown event of the {@link Ext.KeyMap KeyMap} * when the user wants to open an item from reminder dialog. * @param {Number} key Key code * @param {Ext.EventObject} event The event * @param {Ext.Component} component The component on which key event is fired. */ onOpenReminder: function(key, event, component) { var records = this.getSelectedRecords(component); if(!Ext.isEmpty(records)) { for(var i = 0, len = records.length; i < len; i++){ Zarafa.common.Actions.openReminderRecord(records[i]); } } }, /** * Event handler for the keydown event of the {@link Ext.KeyMap KeyMap} * when the user wants to select all items below or above the current selected item {@link Zarafa.common.ui.grid.GridPanel}. * @param {Number} key Key code * @param {Ext.EventObject} event The event * @param {Ext.Component} component The component on which key event is fired. */ onSelectUpDown: function(key, event, component) { var store = component.getStore(); var selectionRange = null; if(key === Ext.EventObject.HOME) { selectionRange = 0; } else if (key === Ext.EventObject.END) { selectionRange = store.getCount(); } if(Ext.isFunction(component.selectRange)) { var selected = component.getSelectedRecords(); if(!Ext.isEmpty(selected)) { component.selectRange(store.indexOf(selected[0]), selectionRange); } } else if(Ext.isFunction(component.getSelectionModel)) { var selectionModel = component.getSelectionModel(); var selected = selectionModel.getSelected(); if(selected) { if(!selectionModel.singleSelect) { // retrieve selected index var index = store.indexOf(selected); // select range from current item till last range selectionModel.selectRange(index,selectionRange); } } } }, /** * Event handler for the keydown event of the {@link Ext.KeyMap KeyMap} * when the user wants to select all items in the {@link Zarafa.common.ui.grid.GridPanel}. * @param {Number} key Key code * @param {Ext.EventObject} event The event * @param {Ext.Component} component The component on which key event is fired. */ onSelectAll: function(key, event, component) { if(Ext.isFunction(component.selectRange)) { // Select all elements for data-views. component.selectRange(); } else if(Ext.isFunction(component.getSelectionModel)) { // Select all elements for components with selection model, e.g. grids. var selectionModel = component.getSelectionModel(); if(!selectionModel.singleSelect) { selectionModel.selectAll(); } } } }); Zarafa.common.KeyMapping = new Zarafa.common.KeyMapping();