mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Add configurable shortcut keys for various common options in the main window. Fixes #2899
This commit is contained in:
committed by
Dave Page
parent
e16a952753
commit
258b064963
@@ -26,7 +26,20 @@ When using main browser window, the following keyboard shortcuts are available:
|
|||||||
| Alt+Shift+[ | Move tabbed panel backward/forward |
|
| Alt+Shift+[ | Move tabbed panel backward/forward |
|
||||||
| Alt+Shift+] | |
|
| 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 |
|
||||||
|
+---------------------------+--------------------------------------------------------+
|
||||||
|
|
||||||
**SQL Editors**
|
**SQL Editors**
|
||||||
|
|
||||||
|
|||||||
@@ -324,6 +324,112 @@ class BrowserModule(PgAdminModule):
|
|||||||
category_label=gettext('Keyboard shortcuts'),
|
category_label=gettext('Keyboard shortcuts'),
|
||||||
fields=fields
|
fields=fields
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.preference.register(
|
||||||
|
'keyboard_shortcuts',
|
||||||
|
'sub_menu_query_tool',
|
||||||
|
gettext('Open query tool'),
|
||||||
|
'keyboardshortcut',
|
||||||
|
{
|
||||||
|
'alt': True,
|
||||||
|
'shift': True,
|
||||||
|
'control': False,
|
||||||
|
'key': {'key_code': 81, 'char': 'q'}
|
||||||
|
},
|
||||||
|
category_label=gettext('Keyboard shortcuts'),
|
||||||
|
fields=fields
|
||||||
|
)
|
||||||
|
|
||||||
|
self.preference.register(
|
||||||
|
'keyboard_shortcuts',
|
||||||
|
'sub_menu_view_data',
|
||||||
|
gettext('View data'),
|
||||||
|
'keyboardshortcut',
|
||||||
|
{
|
||||||
|
'alt': True,
|
||||||
|
'shift': True,
|
||||||
|
'control': False,
|
||||||
|
'key': {'key_code': 86, 'char': 'v'}
|
||||||
|
},
|
||||||
|
category_label=gettext('Keyboard shortcuts'),
|
||||||
|
fields=fields
|
||||||
|
)
|
||||||
|
|
||||||
|
self.preference.register(
|
||||||
|
'keyboard_shortcuts',
|
||||||
|
'sub_menu_create',
|
||||||
|
gettext('Create object'),
|
||||||
|
'keyboardshortcut',
|
||||||
|
{
|
||||||
|
'alt': True,
|
||||||
|
'shift': True,
|
||||||
|
'control': False,
|
||||||
|
'key': {'key_code': 78, 'char': 'n'}
|
||||||
|
},
|
||||||
|
category_label=gettext('Keyboard shortcuts'),
|
||||||
|
fields=fields
|
||||||
|
)
|
||||||
|
|
||||||
|
self.preference.register(
|
||||||
|
'keyboard_shortcuts',
|
||||||
|
'sub_menu_properties',
|
||||||
|
gettext('Edit object properties'),
|
||||||
|
'keyboardshortcut',
|
||||||
|
{
|
||||||
|
'alt': True,
|
||||||
|
'shift': True,
|
||||||
|
'control': False,
|
||||||
|
'key': {'key_code': 69, 'char': 'e'}
|
||||||
|
},
|
||||||
|
category_label=gettext('Keyboard shortcuts'),
|
||||||
|
fields=fields
|
||||||
|
)
|
||||||
|
|
||||||
|
self.preference.register(
|
||||||
|
'keyboard_shortcuts',
|
||||||
|
'sub_menu_delete',
|
||||||
|
gettext('Delete object'),
|
||||||
|
'keyboardshortcut',
|
||||||
|
{
|
||||||
|
'alt': True,
|
||||||
|
'shift': True,
|
||||||
|
'control': False,
|
||||||
|
'key': {'key_code': 68, 'char': 'd'}
|
||||||
|
},
|
||||||
|
category_label=gettext('Keyboard shortcuts'),
|
||||||
|
fields=fields
|
||||||
|
)
|
||||||
|
|
||||||
|
self.preference.register(
|
||||||
|
'keyboard_shortcuts',
|
||||||
|
'context_menu',
|
||||||
|
gettext('Open context menu'),
|
||||||
|
'keyboardshortcut',
|
||||||
|
{
|
||||||
|
'alt': True,
|
||||||
|
'shift': True,
|
||||||
|
'control': False,
|
||||||
|
'key': {'key_code': 67, 'char': 'c'}
|
||||||
|
},
|
||||||
|
category_label=gettext('Keyboard shortcuts'),
|
||||||
|
fields=fields
|
||||||
|
)
|
||||||
|
|
||||||
|
self.preference.register(
|
||||||
|
'keyboard_shortcuts',
|
||||||
|
'direct_debugging',
|
||||||
|
gettext('Direct debugging'),
|
||||||
|
'keyboardshortcut',
|
||||||
|
{
|
||||||
|
'alt': True,
|
||||||
|
'shift': True,
|
||||||
|
'control': False,
|
||||||
|
'key': {'key_code': 71, 'char': 'g'}
|
||||||
|
},
|
||||||
|
category_label=gettext('Keyboard shortcuts'),
|
||||||
|
fields=fields
|
||||||
|
)
|
||||||
|
|
||||||
def get_exposed_url_endpoints(self):
|
def get_exposed_url_endpoints(self):
|
||||||
"""
|
"""
|
||||||
Returns:
|
Returns:
|
||||||
|
|||||||
@@ -428,6 +428,12 @@ define('pgadmin.browser', [
|
|||||||
items: context_menu,
|
items: context_menu,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
events: {
|
||||||
|
hide: function() {
|
||||||
|
// Return focus to the tree
|
||||||
|
obj.keyboardNavigation.bindLeftTree();
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Treeview event handler
|
// Treeview event handler
|
||||||
|
|||||||
@@ -12,14 +12,22 @@ function(_, S, pgAdmin, $, Mousetrap) {
|
|||||||
init: function() {
|
init: function() {
|
||||||
Mousetrap.reset();
|
Mousetrap.reset();
|
||||||
if (pgBrowser.preferences_cache.length > 0) {
|
if (pgBrowser.preferences_cache.length > 0) {
|
||||||
|
var getShortcut = this.parseShortcutValue;
|
||||||
this.keyboardShortcut = {
|
this.keyboardShortcut = {
|
||||||
'file_shortcut': pgBrowser.keyboardNavigation.parseShortcutValue(pgBrowser.get_preference('browser', 'main_menu_file').value),
|
'file_shortcut': getShortcut(pgBrowser.get_preference('browser', 'main_menu_file').value),
|
||||||
'object_shortcut': pgBrowser.keyboardNavigation.parseShortcutValue(pgBrowser.get_preference('browser', 'main_menu_object').value),
|
'object_shortcut': getShortcut(pgBrowser.get_preference('browser', 'main_menu_object').value),
|
||||||
'tools_shortcut': pgBrowser.keyboardNavigation.parseShortcutValue(pgBrowser.get_preference('browser', 'main_menu_tools').value),
|
'tools_shortcut': getShortcut(pgBrowser.get_preference('browser', 'main_menu_tools').value),
|
||||||
'help_shortcut': pgBrowser.keyboardNavigation.parseShortcutValue(pgBrowser.get_preference('browser', 'main_menu_help').value),
|
'help_shortcut': getShortcut(pgBrowser.get_preference('browser', 'main_menu_help').value),
|
||||||
'left_tree_shortcut': pgBrowser.keyboardNavigation.parseShortcutValue(pgBrowser.get_preference('browser', 'browser_tree').value),
|
'left_tree_shortcut': getShortcut(pgBrowser.get_preference('browser', 'browser_tree').value),
|
||||||
'tabbed_panel_backward': pgBrowser.keyboardNavigation.parseShortcutValue(pgBrowser.get_preference('browser', 'tabbed_panel_backward').value),
|
'tabbed_panel_backward': getShortcut(pgBrowser.get_preference('browser', 'tabbed_panel_backward').value),
|
||||||
'tabbed_panel_forward': pgBrowser.keyboardNavigation.parseShortcutValue(pgBrowser.get_preference('browser', 'tabbed_panel_forward').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)
|
||||||
};
|
};
|
||||||
this.shortcutMethods = {
|
this.shortcutMethods = {
|
||||||
'bindMainMenu': {'shortcuts': [this.keyboardShortcut.file_shortcut,
|
'bindMainMenu': {'shortcuts': [this.keyboardShortcut.file_shortcut,
|
||||||
@@ -29,7 +37,14 @@ function(_, S, pgAdmin, $, Mousetrap) {
|
|||||||
'bindMainMenuLeft': {'shortcuts': 'left', 'bindElem': '.pg-navbar'}, // Main menu
|
'bindMainMenuLeft': {'shortcuts': 'left', 'bindElem': '.pg-navbar'}, // Main menu
|
||||||
'bindMainMenuRight': {'shortcuts': 'right', 'bindElem': '.pg-navbar'}, // Main menu
|
'bindMainMenuRight': {'shortcuts': 'right', 'bindElem': '.pg-navbar'}, // Main menu
|
||||||
'bindMainMenuUpDown': {'shortcuts': ['up', 'down']}, // Main menu
|
'bindMainMenuUpDown': {'shortcuts': ['up', 'down']}, // Main menu
|
||||||
'bindLeftTree': {'shortcuts': this.keyboardShortcut.left_tree_shortcut}, // Main menu
|
'bindLeftTree': {'shortcuts': this.keyboardShortcut.left_tree_shortcut}, // Main menu,
|
||||||
|
'bindSubMenuQueryTool': {'shortcuts': this.keyboardShortcut.sub_menu_query_tool}, // Sub menu - Open Query Tool,
|
||||||
|
'bindSubMenuViewData': {'shortcuts': this.keyboardShortcut.sub_menu_view_data}, // Sub menu - Open View Data,
|
||||||
|
'bindSubMenuProperties': {'shortcuts': this.keyboardShortcut.sub_menu_properties}, // Sub menu - Edit Properties,
|
||||||
|
'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
|
||||||
};
|
};
|
||||||
this.bindShortcuts();
|
this.bindShortcuts();
|
||||||
}
|
}
|
||||||
@@ -41,6 +56,7 @@ function(_, S, pgAdmin, $, Mousetrap) {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
_bindWithMousetrap: function(shortcuts, callback, bindElem) {
|
_bindWithMousetrap: function(shortcuts, callback, bindElem) {
|
||||||
|
var self = this;
|
||||||
if (bindElem) {
|
if (bindElem) {
|
||||||
var elem = document.querySelector(bindElem);
|
var elem = document.querySelector(bindElem);
|
||||||
Mousetrap(elem).bind(shortcuts, function() {
|
Mousetrap(elem).bind(shortcuts, function() {
|
||||||
@@ -48,7 +64,7 @@ function(_, S, pgAdmin, $, Mousetrap) {
|
|||||||
}.bind(elem));
|
}.bind(elem));
|
||||||
} else {
|
} else {
|
||||||
Mousetrap.bind(shortcuts, function() {
|
Mousetrap.bind(shortcuts, function() {
|
||||||
callback.apply(this, arguments);
|
callback.apply(self, arguments);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -60,7 +76,7 @@ function(_, S, pgAdmin, $, Mousetrap) {
|
|||||||
else Mousetrap.unbind(shortcut);
|
else Mousetrap.unbind(shortcut);
|
||||||
},
|
},
|
||||||
bindMainMenu: function(e, combo) {
|
bindMainMenu: function(e, combo) {
|
||||||
var shortcut_obj = pgAdmin.Browser.keyboardNavigation.keyboardShortcut;
|
var shortcut_obj = this.keyboardShortcut;
|
||||||
if (combo == shortcut_obj.file_shortcut) $('#mnu_file a.dropdown-toggle').dropdown('toggle');
|
if (combo == shortcut_obj.file_shortcut) $('#mnu_file a.dropdown-toggle').dropdown('toggle');
|
||||||
if (combo == shortcut_obj.object_shortcut) $('#mnu_obj a.dropdown-toggle').first().dropdown('toggle');
|
if (combo == shortcut_obj.object_shortcut) $('#mnu_obj a.dropdown-toggle').first().dropdown('toggle');
|
||||||
if (combo == shortcut_obj.tools_shortcut) $('#mnu_tools a.dropdown-toggle').dropdown('toggle');
|
if (combo == shortcut_obj.tools_shortcut) $('#mnu_tools a.dropdown-toggle').dropdown('toggle');
|
||||||
@@ -73,7 +89,7 @@ function(_, S, pgAdmin, $, Mousetrap) {
|
|||||||
prevPanel = 1,
|
prevPanel = 1,
|
||||||
activePanelId = 0,
|
activePanelId = 0,
|
||||||
activePanelFlag = false,
|
activePanelFlag = false,
|
||||||
shortcut_obj = pgAdmin.Browser.keyboardNavigation.keyboardShortcut;
|
shortcut_obj = this.keyboardShortcut;
|
||||||
|
|
||||||
_.each(pgAdmin.Browser.docker.findPanels(), function(panel, index){
|
_.each(pgAdmin.Browser.docker.findPanels(), function(panel, index){
|
||||||
if (panel.isVisible() && !activePanelFlag && panel._type != 'browser'){
|
if (panel.isVisible() && !activePanelFlag && panel._type != 'browser'){
|
||||||
@@ -138,11 +154,83 @@ function(_, S, pgAdmin, $, Mousetrap) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
bindLeftTree: function() {
|
bindLeftTree: function() {
|
||||||
var t = pgAdmin.Browser.tree,
|
var tree = this.getTreeDetails();
|
||||||
item = t.selected().length > 0 ? t.selected() : t.first();
|
|
||||||
$('#tree').focus();
|
$('#tree').focus();
|
||||||
t.focus(item);
|
tree.t.focus(tree.i);
|
||||||
t.select(item);
|
tree.t.select(tree.i);
|
||||||
|
},
|
||||||
|
bindSubMenuQueryTool: function() {
|
||||||
|
var tree = this.getTreeDetails();
|
||||||
|
|
||||||
|
if (!tree.d)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Call data grid method to render query tool
|
||||||
|
pgAdmin.DataGrid.show_query_tool('', tree.i);
|
||||||
|
},
|
||||||
|
bindSubMenuViewData: function() {
|
||||||
|
var tree = this.getTreeDetails();
|
||||||
|
|
||||||
|
if (!tree.d)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Call data grid method to render view data
|
||||||
|
pgAdmin.DataGrid.show_data_grid({'mnuid': 1}, tree.i);
|
||||||
|
},
|
||||||
|
bindSubMenuProperties: function() {
|
||||||
|
var tree = this.getTreeDetails();
|
||||||
|
|
||||||
|
if (!tree.d || pgAdmin.Browser.Nodes[tree.t.itemData(tree.i)._type].collection_node == true)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Open properties dialog in edit mode
|
||||||
|
pgAdmin.Browser.Node.callbacks.show_obj_properties.call(
|
||||||
|
pgAdmin.Browser.Nodes[tree.t.itemData(tree.i)._type], {action: 'edit'}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
bindSubMenuCreate: function() {
|
||||||
|
var tree = this.getTreeDetails();
|
||||||
|
|
||||||
|
if (!tree.d || pgAdmin.Browser.Nodes[tree.t.itemData(tree.i)._type].collection_node == true)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Open properties dialog in edit mode
|
||||||
|
pgAdmin.Browser.Node.callbacks.show_obj_properties.call(
|
||||||
|
pgAdmin.Browser.Nodes[tree.t.itemData(tree.i)._type], {action: 'create'}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
bindSubMenuDelete: function() {
|
||||||
|
var tree = this.getTreeDetails();
|
||||||
|
|
||||||
|
if (!tree.d || pgAdmin.Browser.Nodes[tree.t.itemData(tree.i)._type].collection_node == true)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Call delete object callback
|
||||||
|
pgAdmin.Browser.Node.callbacks.delete_obj.call(pgAdmin.Browser.Nodes[tree.t.itemData(tree.i)._type]);
|
||||||
|
},
|
||||||
|
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;
|
||||||
|
|
||||||
|
tree.t.blur(tree.i);
|
||||||
|
$('#tree').blur();
|
||||||
|
// Call context menu and set position
|
||||||
|
var ctx = tree.i.children().contextMenu({x: left, y:top});
|
||||||
|
},
|
||||||
|
bindDirectDebugging: function(e) {
|
||||||
|
var tree = this.getTreeDetails(),
|
||||||
|
type = tree.t.itemData(tree.i)._type;
|
||||||
|
|
||||||
|
if (!tree.d || (type != 'function' && type != 'procedure'))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(pgAdmin.Tools.Debugger.can_debug(tree.d, tree.i, {'debug_type': 'direct'})) {
|
||||||
|
// Call debugger callback
|
||||||
|
pgAdmin.Tools.Debugger.get_function_information(pgAdmin.Browser.Nodes[type]);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
parseShortcutValue: function(obj) {
|
parseShortcutValue: function(obj) {
|
||||||
var shortcut = "";
|
var shortcut = "";
|
||||||
@@ -151,6 +239,17 @@ function(_, S, pgAdmin, $, Mousetrap) {
|
|||||||
if (obj.control) { shortcut += 'ctrl+'; }
|
if (obj.control) { shortcut += 'ctrl+'; }
|
||||||
shortcut += String.fromCharCode(obj.key.key_code).toLowerCase();
|
shortcut += String.fromCharCode(obj.key.key_code).toLowerCase();
|
||||||
return shortcut;
|
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;
|
||||||
|
|
||||||
|
return {
|
||||||
|
t: t,
|
||||||
|
i: i,
|
||||||
|
d: d
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -519,7 +519,7 @@ define('pgadmin.browser.node', [
|
|||||||
**/
|
**/
|
||||||
show_obj_properties: function(args, item) {
|
show_obj_properties: function(args, item) {
|
||||||
var t = pgBrowser.tree,
|
var t = pgBrowser.tree,
|
||||||
i = args.item || item || t.selected(),
|
i = (args && args.item) || item || t.selected(),
|
||||||
d = i && i.length == 1 ? t.itemData(i) : undefined,
|
d = i && i.length == 1 ? t.itemData(i) : undefined,
|
||||||
o = this,
|
o = this,
|
||||||
l = o.title.apply(this, [d]);
|
l = o.title.apply(this, [d]);
|
||||||
|
|||||||
Reference in New Issue
Block a user