diff --git a/docs/en_US/keyboard_shortcuts.rst b/docs/en_US/keyboard_shortcuts.rst index 1142975..af840ad 100644 --- a/docs/en_US/keyboard_shortcuts.rst +++ b/docs/en_US/keyboard_shortcuts.rst @@ -10,36 +10,51 @@ desired.˝ When using main browser window, the following keyboard shortcuts are available: -+---------------------------+--------------------------------------------------------+ -| Shortcut for all platform | Function | -+===========================+========================================================+ -| Alt+Shift+F | Open the File menu | -+---------------------------+--------------------------------------------------------+ -| Alt+Shift+O | Open the Object menu | -+---------------------------+--------------------------------------------------------+ -| Alt+Shift+L | Open the Tools menu | -+---------------------------+--------------------------------------------------------+ -| Alt+Shift+H | Open the Help menu | -+---------------------------+--------------------------------------------------------+ -| Alt+Shift+B | Focus the browser tree | -+---------------------------+--------------------------------------------------------+ -| Alt+Shift+[ | Move tabbed panel backward/forward | -| Alt+Shift+] | | -+---------------------------+--------------------------------------------------------+ -| Alt+Shift+Q | Open the Query Tool in the current database | -+---------------------------+--------------------------------------------------------+ -| Alt+Shift+V | View Data in the selected table/view | -+---------------------------+--------------------------------------------------------+ -| Alt+Shift+C | Open the context menu | -+---------------------------+--------------------------------------------------------+ -| Alt+Shift+N | Create an object | -+---------------------------+--------------------------------------------------------+ -| Alt+Shift+E | Edit object properties | -+---------------------------+--------------------------------------------------------+ -| Alt+Shift+D | Delete the object | -+---------------------------+--------------------------------------------------------+ -| Alt+Shift+G | Direct debugging | -+---------------------------+--------------------------------------------------------+ ++----------------------------+-------------------------------------------------------+ +| Shortcut for all platforms | Function | ++============================+=======================================================+ +| Alt+Shift+F | Open the File menu | ++----------------------------+-------------------------------------------------------+ +| Alt+Shift+O | Open the Object menu | ++----------------------------+-------------------------------------------------------+ +| Alt+Shift+L | Open the Tools menu | ++----------------------------+-------------------------------------------------------+ +| Alt+Shift+H | Open the Help menu | ++----------------------------+-------------------------------------------------------+ +| Alt+Shift+B | Focus the browser tree | ++----------------------------+-------------------------------------------------------+ +| Alt+Shift+[ | Move tabbed panel backward | ++----------------------------+-------------------------------------------------------+ +| Alt+Shift+] | Move tabbed panel forward | ++----------------------------+-------------------------------------------------------+ +| Alt+Shift+Q | Open the Query Tool in the current database | ++----------------------------+-------------------------------------------------------+ +| Alt+Shift+V | View Data in the selected table/view | ++----------------------------+-------------------------------------------------------+ +| Alt+Shift+C | Open the context menu | ++----------------------------+-------------------------------------------------------+ +| Alt+Shift+N | Create an object | ++----------------------------+-------------------------------------------------------+ +| Alt+Shift+E | Edit object properties | ++----------------------------+-------------------------------------------------------+ +| Alt+Shift+D | Delete the object | ++----------------------------+-------------------------------------------------------+ +| Alt+Shift+G | Direct debugging | ++----------------------------+-------------------------------------------------------+ + + +**Dialog tab shortcuts** + +Use the shortcuts below to navigate the tabsets on dialogs: + ++----------------------------+-------------------------------------------------------+ +| Shortcut for all platforms | Function | ++============================+=======================================================+ +| Control+Shift+[ | Dialog tab backward | ++----------------------------+-------------------------------------------------------+ +| Control+Shift+] | Dialog tab forward | ++----------------------------+-------------------------------------------------------+ + **SQL Editors** diff --git a/web/pgadmin/browser/__init__.py b/web/pgadmin/browser/__init__.py index 9faa564..ca1edd0 100644 --- a/web/pgadmin/browser/__init__.py +++ b/web/pgadmin/browser/__init__.py @@ -433,6 +433,36 @@ class BrowserModule(PgAdminModule): fields=fields ) + self.preference.register( + 'keyboard_shortcuts', + 'dialog_tab_forward', + gettext('Dialog tab forward'), + 'keyboardshortcut', + { + 'alt': False, + 'shift': True, + 'control': True, + 'key': {'key_code': 93, 'char': ']'} + }, + category_label=gettext('Keyboard shortcuts'), + fields=fields + ) + + self.preference.register( + 'keyboard_shortcuts', + 'dialog_tab_backward', + gettext('Dialog tab backward'), + 'keyboardshortcut', + { + 'alt': False, + 'shift': True, + 'control': True, + 'key': {'key_code': 91, 'char': '['} + }, + category_label=gettext('Keyboard shortcuts'), + fields=fields + ) + def get_exposed_url_endpoints(self): """ Returns: diff --git a/web/pgadmin/browser/static/js/keyboard.js b/web/pgadmin/browser/static/js/keyboard.js index 95b77db..5c71b80 100644 --- a/web/pgadmin/browser/static/js/keyboard.js +++ b/web/pgadmin/browser/static/js/keyboard.js @@ -1,7 +1,6 @@ -/* eslint-disable */ -define( - ['underscore', 'underscore.string', 'sources/pgadmin', 'jquery', 'mousetrap'], -function(_, S, pgAdmin, $, Mousetrap) { +define(['underscore', 'underscore.string', 'sources/pgadmin', 'jquery', 'mousetrap', + 'sources/utils', 'sources/dialog_tab_navigator'], +function(_, S, pgAdmin, $, Mousetrap, commonUtils, dialogTabNavigator) { 'use strict'; var pgBrowser = pgAdmin.Browser = pgAdmin.Browser || {}; @@ -12,27 +11,26 @@ function(_, S, pgAdmin, $, Mousetrap) { init: function() { Mousetrap.reset(); if (pgBrowser.preferences_cache.length > 0) { - var getShortcut = this.parseShortcutValue; this.keyboardShortcut = { - 'file_shortcut': getShortcut(pgBrowser.get_preference('browser', 'main_menu_file').value), - 'object_shortcut': getShortcut(pgBrowser.get_preference('browser', 'main_menu_object').value), - 'tools_shortcut': getShortcut(pgBrowser.get_preference('browser', 'main_menu_tools').value), - 'help_shortcut': getShortcut(pgBrowser.get_preference('browser', 'main_menu_help').value), - 'left_tree_shortcut': getShortcut(pgBrowser.get_preference('browser', 'browser_tree').value), - 'tabbed_panel_backward': getShortcut(pgBrowser.get_preference('browser', 'tabbed_panel_backward').value), - 'tabbed_panel_forward': getShortcut(pgBrowser.get_preference('browser', 'tabbed_panel_forward').value), - 'sub_menu_query_tool': getShortcut(pgBrowser.get_preference('browser', 'sub_menu_query_tool').value), - 'sub_menu_view_data': getShortcut(pgBrowser.get_preference('browser', 'sub_menu_view_data').value), - 'sub_menu_properties': getShortcut(pgBrowser.get_preference('browser', 'sub_menu_properties').value), - 'sub_menu_create': getShortcut(pgBrowser.get_preference('browser', 'sub_menu_create').value), - 'sub_menu_delete': getShortcut(pgBrowser.get_preference('browser', 'sub_menu_delete').value), - 'context_menu': getShortcut(pgBrowser.get_preference('browser', 'context_menu').value), - 'direct_debugging': getShortcut(pgBrowser.get_preference('browser', 'direct_debugging').value) + 'file_shortcut': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'main_menu_file').value), + 'object_shortcut': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'main_menu_object').value), + 'tools_shortcut': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'main_menu_tools').value), + 'help_shortcut': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'main_menu_help').value), + 'left_tree_shortcut': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'browser_tree').value), + 'tabbed_panel_backward': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'tabbed_panel_backward').value), + 'tabbed_panel_forward': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'tabbed_panel_forward').value), + 'sub_menu_query_tool': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'sub_menu_query_tool').value), + 'sub_menu_view_data': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'sub_menu_view_data').value), + 'sub_menu_properties': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'sub_menu_properties').value), + 'sub_menu_create': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'sub_menu_create').value), + 'sub_menu_delete': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'sub_menu_delete').value), + 'context_menu': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'context_menu').value), + 'direct_debugging': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'direct_debugging').value), }; this.shortcutMethods = { 'bindMainMenu': {'shortcuts': [this.keyboardShortcut.file_shortcut, - this.keyboardShortcut.object_shortcut, this.keyboardShortcut.tools_shortcut, - this.keyboardShortcut.help_shortcut]}, // Main menu + this.keyboardShortcut.object_shortcut, this.keyboardShortcut.tools_shortcut, + this.keyboardShortcut.help_shortcut]}, // Main menu 'bindRightPanel': {'shortcuts': [this.keyboardShortcut.tabbed_panel_backward, this.keyboardShortcut.tabbed_panel_forward]}, // Main window panels 'bindMainMenuLeft': {'shortcuts': 'left', 'bindElem': '.pg-navbar'}, // Main menu 'bindMainMenuRight': {'shortcuts': 'right', 'bindElem': '.pg-navbar'}, // Main menu @@ -44,9 +42,9 @@ function(_, S, pgAdmin, $, Mousetrap) { 'bindSubMenuCreate': {'shortcuts': this.keyboardShortcut.sub_menu_create}, // Sub menu - Create Object, 'bindSubMenuDelete': {'shortcuts': this.keyboardShortcut.sub_menu_delete}, // Sub menu - Delete object, 'bindContextMenu': {'shortcuts': this.keyboardShortcut.context_menu}, // Sub menu - Open context menu, - 'bindDirectDebugging': {'shortcuts': this.keyboardShortcut.direct_debugging} // Sub menu - Direct Debugging + 'bindDirectDebugging': {'shortcuts': this.keyboardShortcut.direct_debugging}, // Sub menu - Direct Debugging }; - this.bindShortcuts(); + this.bindShortcuts(); } }, bindShortcuts: function() { @@ -71,6 +69,20 @@ function(_, S, pgAdmin, $, Mousetrap) { attachShortcut: function(shortcut, callback, bindElem) { this._bindWithMousetrap(shortcut, callback, bindElem); }, + attachDialogTabNavigatorShortcut: function(dialogTabNavigator, shortcuts) { + var callback = dialogTabNavigator.on_keyboard_event, + domElem = dialogTabNavigator.dialog.el; + + if (domElem) { + Mousetrap(domElem).bind(shortcuts, function() { + callback.apply(dialogTabNavigator, arguments); + }.bind(domElem)); + } else { + Mousetrap.bind(shortcuts, function() { + callback.apply(dialogTabNavigator, arguments); + }); + } + }, detachShortcut: function(shortcut, bindElem) { if (bindElem) Mousetrap(bindElem).unbind(shortcut); else Mousetrap.unbind(shortcut); @@ -211,18 +223,18 @@ function(_, S, pgAdmin, $, Mousetrap) { }, bindContextMenu: function(e) { var tree = this.getTreeDetails(), - e = window.event, - left = $(e.srcElement).find('.aciTreeEntry').position().left + 70, - top = $(e.srcElement).find('.aciTreeEntry').position().top + 70; + left = $(e.srcElement).find('.aciTreeEntry').position().left + 70, + top = $(e.srcElement).find('.aciTreeEntry').position().top + 70; + e = window.event; tree.t.blur(tree.i); $('#tree').blur(); // Call context menu and set position - var ctx = tree.i.children().contextMenu({x: left, y:top}); + tree.i.children().contextMenu({x: left, y:top}); }, - bindDirectDebugging: function(e) { + bindDirectDebugging: function() { var tree = this.getTreeDetails(), - type = tree.t.itemData(tree.i)._type; + type = tree.t.itemData(tree.i)._type; if (!tree.d || (type != 'function' && type != 'procedure')) return; @@ -232,26 +244,23 @@ function(_, S, pgAdmin, $, Mousetrap) { pgAdmin.Tools.Debugger.get_function_information(pgAdmin.Browser.Nodes[type]); } }, - parseShortcutValue: function(obj) { - var shortcut = ""; - if (obj.alt) { shortcut += 'alt+'; } - if (obj.shift) { shortcut += 'shift+'; } - if (obj.control) { shortcut += 'ctrl+'; } - shortcut += String.fromCharCode(obj.key.key_code).toLowerCase(); - return shortcut; - }, getTreeDetails: function() { var t = pgAdmin.Browser.tree, - i = t.selected().length > 0 ? t.selected() : t.first(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + i = t.selected().length > 0 ? t.selected() : t.first(), + d = i && i.length == 1 ? t.itemData(i) : undefined; return { t: t, i: i, - d: d - } - } + d: d, + }; + }, + getDialogTabNavigator: function(dialog) { + var backward_shortcut = pgBrowser.get_preference('browser', 'dialog_tab_backward').value, + forward_shortcut = pgBrowser.get_preference('browser', 'dialog_tab_forward').value; + return new dialogTabNavigator.dialogTabNavigator(dialog, backward_shortcut, forward_shortcut); + }, }); return pgAdmin.keyboardNavigation; diff --git a/web/pgadmin/browser/static/js/node.js b/web/pgadmin/browser/static/js/node.js index 250bd5d..ad58248 100644 --- a/web/pgadmin/browser/static/js/node.js +++ b/web/pgadmin/browser/static/js/node.js @@ -1,8 +1,9 @@ define('pgadmin.browser.node', [ 'sources/gettext', 'jquery', 'underscore', 'underscore.string', 'sources/pgadmin', 'pgadmin.browser.menu', 'backbone', 'pgadmin.alertifyjs', 'pgadmin.browser.datamodel', - 'backform', 'sources/browser/generate_url', 'pgadmin.browser.utils', 'pgadmin.backform', -], function(gettext, $, _, S, pgAdmin, Menu, Backbone, Alertify, pgBrowser, Backform, generateUrl) { + 'backform', 'sources/browser/generate_url', 'sources/utils', 'pgadmin.browser.utils', + 'pgadmin.backform', +], function(gettext, $, _, S, pgAdmin, Menu, Backbone, Alertify, pgBrowser, Backform, generateUrl, commonUtils) { var wcDocker = window.wcDocker, keyCode = { @@ -365,9 +366,8 @@ define('pgadmin.browser.node', [ } var setFocusOnEl = function() { - setTimeout(function() { - $(el).find('.tab-pane.active:first').find('input:first').focus(); - }, 500); + var container = $(el).find('.tab-content:first > .tab-pane.active:first'); + commonUtils.findAndSetFocus(container); }; if (!newModel.isNew()) { @@ -394,6 +394,8 @@ define('pgadmin.browser.node', [ view.render(); setFocusOnEl(); newModel.startNewSession(); + // var dialogTabNavigator = pgBrowser.keyboardNavigation.getDialogTabNavigator(view); + pgBrowser.keyboardNavigation.getDialogTabNavigator(view); }, error: function(xhr, error, message) { var _label = that && item ? @@ -430,8 +432,11 @@ define('pgadmin.browser.node', [ view.render(); setFocusOnEl(); newModel.startNewSession(); + // var dialogTabNavigator = pgBrowser.keyboardNavigation.getDialogTabNavigator(view); + pgBrowser.keyboardNavigation.getDialogTabNavigator(view); } } + return view; } diff --git a/web/pgadmin/browser/static/js/wizard.js b/web/pgadmin/browser/static/js/wizard.js index 56b1edf..ef59b00 100644 --- a/web/pgadmin/browser/static/js/wizard.js +++ b/web/pgadmin/browser/static/js/wizard.js @@ -1,7 +1,7 @@ define([ 'underscore', 'jquery', 'backbone', 'sources/pgadmin', 'pgadmin.browser', - 'sources/gettext', -], function(_, $, Backbone, pgAdmin, pgBrowser, gettext) { + 'sources/gettext', 'sources/utils', +], function(_, $, Backbone, pgAdmin, pgBrowser, gettext, commonUtils) { var wcDocker = window.wcDocker; @@ -157,7 +157,8 @@ define([ this.currPage = this.collection.at(this.options.curr_page).toJSON(); }, render: function() { - var data = this.currPage; + var self = this, + data = this.currPage; /* Check Status of the buttons */ this.options.disable_next = (this.options.disable_next ? true : this.evalASFunc(this.currPage.disable_next)); @@ -179,6 +180,11 @@ define([ /* OnLoad Callback */ this.onLoad(); + setTimeout(function() { + var container = $(self.el); + commonUtils.findAndSetFocus(container); + }, 100); + return this; }, nextPage: function() { diff --git a/web/pgadmin/static/js/backform.pgadmin.js b/web/pgadmin/static/js/backform.pgadmin.js index 2bbaa17..5bbbf9f 100644 --- a/web/pgadmin/static/js/backform.pgadmin.js +++ b/web/pgadmin/static/js/backform.pgadmin.js @@ -500,12 +500,12 @@ define([ template: { 'header': _.template([ '