Add keyboard shortcuts for the Query Tool. Fixes #2900
parent
055f7abc9e
commit
a9de043fef
Binary file not shown.
After Width: | Height: | Size: 135 KiB |
|
@ -91,7 +91,17 @@ When using the syntax-highlighting SQL editors, the following shortcuts are avai
|
||||||
+--------------------------+------------------+-------------------------------------+
|
+--------------------------+------------------+-------------------------------------+
|
||||||
| Shift+Tab | Shift+Tab | Un-indent selected text |
|
| Shift+Tab | Shift+Tab | Un-indent selected text |
|
||||||
+--------------------------+------------------+-------------------------------------+
|
+--------------------------+------------------+-------------------------------------+
|
||||||
| <accesskey> + y | <accesskey> + y | Copy SQL on history panel |
|
| Alt+G | Alt+G | Jump (to line:column) |
|
||||||
|
+--------------------------+------------------+-------------------------------------+
|
||||||
|
| Ctrl+Space | Ctrl+Space | Auto-complete |
|
||||||
|
+--------------------------+------------------+-------------------------------------+
|
||||||
|
| Ctrl+F | Cmd+F | Find |
|
||||||
|
+--------------------------+------------------+-------------------------------------+
|
||||||
|
| Ctrl+G | Cmd+G | Find next |
|
||||||
|
+--------------------------+------------------+-------------------------------------+
|
||||||
|
| Ctrl+Shift+G | Cmd+Shift+G | Find previous |
|
||||||
|
+--------------------------+------------------+-------------------------------------+
|
||||||
|
| Ctrl+Shift+F | Cmd+Shift+F | Replace |
|
||||||
+--------------------------+------------------+-------------------------------------+
|
+--------------------------+------------------+-------------------------------------+
|
||||||
|
|
||||||
|
|
||||||
|
@ -110,17 +120,31 @@ When using the Query Tool, the following shortcuts are available:
|
||||||
+--------------------------+--------------------+-----------------------------------+
|
+--------------------------+--------------------+-----------------------------------+
|
||||||
| F8 | F8 | Execute query to CSV file |
|
| F8 | F8 | Execute query to CSV file |
|
||||||
+--------------------------+--------------------+-----------------------------------+
|
+--------------------------+--------------------+-----------------------------------+
|
||||||
| Alt+G | Alt+G | Jump (to line:column) |
|
| <accesskey> + o | <accesskey> + o | Open file |
|
||||||
+--------------------------+--------------------+-----------------------------------+
|
+--------------------------+--------------------+-----------------------------------+
|
||||||
| Ctrl+Space | Ctrl+Space | Auto-complete |
|
| <accesskey> + s | <accesskey> + s | Save file |
|
||||||
+--------------------------+--------------------+-----------------------------------+
|
+--------------------------+--------------------+-----------------------------------+
|
||||||
| Ctrl+F | Cmd+F | Find |
|
| <accesskey> + n | <accesskey> + n | Find option drop down |
|
||||||
+--------------------------+--------------------+-----------------------------------+
|
+--------------------------+--------------------+-----------------------------------+
|
||||||
| Ctrl+G | Cmd+G | Find next |
|
| <accesskey> + c | <accesskey> + c | Copy row(s) |
|
||||||
+--------------------------+--------------------+-----------------------------------+
|
+--------------------------+--------------------+-----------------------------------+
|
||||||
| Ctrl+Shift+G | Cmd+Shift+G | Find previous |
|
| <accesskey> + p | <accesskey> + p | Paste row(s) |
|
||||||
+--------------------------+--------------------+-----------------------------------+
|
+--------------------------+--------------------+-----------------------------------+
|
||||||
| Ctrl+Shift+F | Cmd+Shift+F | Replace |
|
| <accesskey> + d | <accesskey> + d | Delete row(s) |
|
||||||
|
+--------------------------+--------------------+-----------------------------------+
|
||||||
|
| <accesskey> + f | <accesskey> + f | Filter dialog |
|
||||||
|
+--------------------------+--------------------+-----------------------------------+
|
||||||
|
| <accesskey> + i | <accesskey> + i | Filter options drop down |
|
||||||
|
+--------------------------+--------------------+-----------------------------------+
|
||||||
|
| <accesskey> + r | <accesskey> + r | Row limit |
|
||||||
|
+--------------------------+--------------------+-----------------------------------+
|
||||||
|
| <accesskey> + q | <accesskey> + q | Cancel query |
|
||||||
|
+--------------------------+--------------------+-----------------------------------+
|
||||||
|
| <accesskey> + l | <accesskey> + l | Clear option drop down |
|
||||||
|
+--------------------------+--------------------+-----------------------------------+
|
||||||
|
| <accesskey> + x | <accesskey> + x | Execute option drop down |
|
||||||
|
+--------------------------+--------------------+-----------------------------------+
|
||||||
|
| <accesskey> + t | <accesskey> + t | Display connection status |
|
||||||
+--------------------------+--------------------+-----------------------------------+
|
+--------------------------+--------------------+-----------------------------------+
|
||||||
| <accesskey> + y | <accesskey> + y | Copy SQL on history panel |
|
| <accesskey> + y | <accesskey> + y | Copy SQL on history panel |
|
||||||
+--------------------------+--------------------+-----------------------------------+
|
+--------------------------+--------------------+-----------------------------------+
|
||||||
|
|
|
@ -190,6 +190,11 @@ Use the fields on the *Results grid* panel to specify your formatting preference
|
||||||
* Use the *Result copy quote character* drop-down listbox to select the quote character for copied data.
|
* Use the *Result copy quote character* drop-down listbox to select the quote character for copied data.
|
||||||
* Use the *Result copy quoting* drop-down listbox to select which type of fields require quoting; select *All*, *None*, or *Strings*.
|
* Use the *Result copy quoting* drop-down listbox to select which type of fields require quoting; select *All*, *None*, or *Strings*.
|
||||||
|
|
||||||
|
Use the fields on the *Keyboard shortcuts* panel to configure shortcuts for the sql editor window navigation:
|
||||||
|
|
||||||
|
.. image:: images/preferences_sql_keyboard_shortcuts.png
|
||||||
|
:alt: Preferences dialog sql keyboard shortcuts section
|
||||||
|
|
||||||
**The Storage Node**
|
**The Storage Node**
|
||||||
|
|
||||||
Expand the *Storage* node to specify your storage preferences.
|
Expand the *Storage* node to specify your storage preferences.
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
|
|
||||||
const LEFT_ARROW_KEY = 37,
|
const PERIOD_KEY = 190,
|
||||||
RIGHT_ARROW_KEY = 39,
|
|
||||||
F5_KEY = 116,
|
|
||||||
F7_KEY = 118,
|
|
||||||
F8_KEY = 119,
|
|
||||||
PERIOD_KEY = 190,
|
|
||||||
FWD_SLASH_KEY = 191,
|
FWD_SLASH_KEY = 191,
|
||||||
ESC_KEY = 27;
|
ESC_KEY = 27;
|
||||||
|
|
||||||
|
@ -115,23 +110,31 @@ function getInnerPanel($el, direction) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Query tool: Keyboard Shortcuts handling */
|
/* Query tool: Keyboard Shortcuts handling */
|
||||||
function keyboardShortcutsQueryTool(sqlEditorController, queryToolActions, event) {
|
function keyboardShortcutsQueryTool(
|
||||||
|
sqlEditorController, keyboardShortcutConfig, queryToolActions, event
|
||||||
|
) {
|
||||||
if (sqlEditorController.isQueryRunning()) {
|
if (sqlEditorController.isQueryRunning()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let keyCode = event.which || event.keyCode, panel_id;
|
let keyCode = event.which || event.keyCode, panel_id;
|
||||||
|
let executeKeys = keyboardShortcutConfig['execute'];
|
||||||
|
let explainKeys = keyboardShortcutConfig['explain'];
|
||||||
|
let explainAnalyzeKeys = keyboardShortcutConfig['explain_analyze'];
|
||||||
|
let downloadCsvKeys = keyboardShortcutConfig['download_csv'];
|
||||||
|
let nextPanelKeys = keyboardShortcutConfig['move_next'];
|
||||||
|
let previousPanelKeys = keyboardShortcutConfig['move_previous'];
|
||||||
|
|
||||||
if (keyCode === F5_KEY) {
|
if (this.validateShortcutKeys(executeKeys, event)) {
|
||||||
event.preventDefault();
|
|
||||||
queryToolActions.executeQuery(sqlEditorController);
|
|
||||||
} else if (event.shiftKey && keyCode === F7_KEY) {
|
|
||||||
this._stopEventPropagation(event);
|
this._stopEventPropagation(event);
|
||||||
queryToolActions.explainAnalyze(sqlEditorController);
|
queryToolActions.executeQuery(sqlEditorController);
|
||||||
} else if (keyCode === F7_KEY) {
|
} else if (this.validateShortcutKeys(explainKeys, event)) {
|
||||||
this._stopEventPropagation(event);
|
this._stopEventPropagation(event);
|
||||||
queryToolActions.explain(sqlEditorController);
|
queryToolActions.explain(sqlEditorController);
|
||||||
} else if (keyCode === F8_KEY) {
|
} else if (this.validateShortcutKeys(explainAnalyzeKeys, event)) {
|
||||||
event.preventDefault();
|
this._stopEventPropagation(event);
|
||||||
|
queryToolActions.explainAnalyze(sqlEditorController);
|
||||||
|
} else if (this.validateShortcutKeys(downloadCsvKeys, event)) {
|
||||||
|
this._stopEventPropagation(event);
|
||||||
queryToolActions.download(sqlEditorController);
|
queryToolActions.download(sqlEditorController);
|
||||||
} else if ((
|
} else if ((
|
||||||
(this.isMac() && event.metaKey) ||
|
(this.isMac() && event.metaKey) ||
|
||||||
|
@ -151,21 +154,16 @@ function keyboardShortcutsQueryTool(sqlEditorController, queryToolActions, event
|
||||||
) && keyCode === PERIOD_KEY) {
|
) && keyCode === PERIOD_KEY) {
|
||||||
this._stopEventPropagation(event);
|
this._stopEventPropagation(event);
|
||||||
queryToolActions.uncommentLineCode(sqlEditorController);
|
queryToolActions.uncommentLineCode(sqlEditorController);
|
||||||
} else if (this.isAltShiftBoth(event) && keyCode === LEFT_ARROW_KEY) {
|
|
||||||
// Goto previous side panel
|
|
||||||
this._stopEventPropagation(event);
|
|
||||||
panel_id = this.getInnerPanel(
|
|
||||||
sqlEditorController.container, 'left'
|
|
||||||
);
|
|
||||||
} else if (this.isAltShiftBoth(event) && keyCode === RIGHT_ARROW_KEY) {
|
|
||||||
// Goto next side panel
|
|
||||||
this._stopEventPropagation(event);
|
|
||||||
panel_id = this.getInnerPanel(
|
|
||||||
sqlEditorController.container, 'right'
|
|
||||||
);
|
|
||||||
} else if (keyCode == ESC_KEY) {
|
} else if (keyCode == ESC_KEY) {
|
||||||
queryToolActions.focusOut(sqlEditorController);
|
queryToolActions.focusOut(sqlEditorController);
|
||||||
|
} else if(this.validateShortcutKeys(nextPanelKeys, event)) {
|
||||||
|
this._stopEventPropagation(event);
|
||||||
|
panel_id = this.getInnerPanel(sqlEditorController.container, 'right');
|
||||||
|
} else if(this.validateShortcutKeys(previousPanelKeys, event)) {
|
||||||
|
this._stopEventPropagation(event);
|
||||||
|
panel_id = this.getInnerPanel(sqlEditorController.container, 'left');
|
||||||
}
|
}
|
||||||
|
|
||||||
return panel_id;
|
return panel_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -114,10 +114,56 @@ let queryToolActions = {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
focusOut: function() {
|
focusOut: function () {
|
||||||
document.activeElement.blur();
|
document.activeElement.blur();
|
||||||
window.top.document.activeElement.blur();
|
window.top.document.activeElement.blur();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getKeyboardShortcuts: function (sqlEditorController) {
|
||||||
|
let executeQueryPref = window.top.pgAdmin.Browser.get_preference(
|
||||||
|
'sqleditor', 'execute_query');
|
||||||
|
let explainQueryPref = window.top.pgAdmin.Browser.get_preference(
|
||||||
|
'sqleditor', 'explain_query');
|
||||||
|
let explainAnalyzeQueryPref = window.top.pgAdmin.Browser.get_preference(
|
||||||
|
'sqleditor', 'explain_analyze_query');
|
||||||
|
let downloadCsvPref = window.top.pgAdmin.Browser.get_preference(
|
||||||
|
'sqleditor', 'download_csv');
|
||||||
|
let nextPanelPerf = window.top.pgAdmin.Browser.get_preference(
|
||||||
|
'sqleditor', 'move_next');
|
||||||
|
let previousPanelPerf = window.top.pgAdmin.Browser.get_preference(
|
||||||
|
'sqleditor', 'move_previous');
|
||||||
|
|
||||||
|
if(!executeQueryPref && sqlEditorController.handler.is_new_browser_tab) {
|
||||||
|
executeQueryPref = window.opener.pgAdmin.Browser.get_preference(
|
||||||
|
'sqleditor', 'execute_query'
|
||||||
|
),
|
||||||
|
explainQueryPref = window.opener.pgAdmin.Browser.get_preference(
|
||||||
|
'sqleditor', 'explain_query'
|
||||||
|
),
|
||||||
|
explainAnalyzeQueryPref = window.opener.pgAdmin.Browser.get_preference(
|
||||||
|
'sqleditor', 'explain_analyze_query'
|
||||||
|
),
|
||||||
|
downloadCsvPref = window.opener.pgAdmin.Browser.get_preference(
|
||||||
|
'sqleditor', 'download_csv'
|
||||||
|
),
|
||||||
|
nextPanelPerf = window.opener.pgAdmin.Browser.get_preference(
|
||||||
|
'sqleditor', 'move_next'
|
||||||
|
),
|
||||||
|
previousPanelPerf = window.opener.pgAdmin.Browser.get_preference(
|
||||||
|
'sqleditor', 'move_previous'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
'execute': executeQueryPref.value,
|
||||||
|
'explain': explainQueryPref.value,
|
||||||
|
'explain_analyze': explainAnalyzeQueryPref.value,
|
||||||
|
'download_csv': downloadCsvPref.value,
|
||||||
|
'move_next': nextPanelPerf.value,
|
||||||
|
'move_previous': previousPanelPerf.value,
|
||||||
|
};
|
||||||
|
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = queryToolActions;
|
module.exports = queryToolActions;
|
||||||
|
|
|
@ -28,6 +28,8 @@ from pgadmin.utils.preferences import Preferences
|
||||||
from pgadmin.model import Server
|
from pgadmin.model import Server
|
||||||
from pgadmin.utils.driver import get_driver
|
from pgadmin.utils.driver import get_driver
|
||||||
from pgadmin.utils.exception import ConnectionLost
|
from pgadmin.utils.exception import ConnectionLost
|
||||||
|
from pgadmin.tools.sqleditor.utils.query_tool_preferences import \
|
||||||
|
get_query_tool_keyboard_shortcuts, get_text_representation_of_shortcut
|
||||||
|
|
||||||
|
|
||||||
class DataGridModule(PgAdminModule):
|
class DataGridModule(PgAdminModule):
|
||||||
|
@ -287,6 +289,7 @@ def panel(trans_id, is_query_tool, editor_title):
|
||||||
url_params['obj_id'] = trans_obj.obj_id
|
url_params['obj_id'] = trans_obj.obj_id
|
||||||
|
|
||||||
display_connection_status = pref.preference('connection_status').get()
|
display_connection_status = pref.preference('connection_status').get()
|
||||||
|
queryToolShortcuts = get_query_tool_keyboard_shortcuts()
|
||||||
|
|
||||||
return render_template(
|
return render_template(
|
||||||
"datagrid/index.html",
|
"datagrid/index.html",
|
||||||
|
@ -306,7 +309,10 @@ def panel(trans_id, is_query_tool, editor_title):
|
||||||
# before passing it to html template.
|
# before passing it to html template.
|
||||||
prompt_save_changes='true' if prompt_save_changes else 'false',
|
prompt_save_changes='true' if prompt_save_changes else 'false',
|
||||||
display_connection_status=display_connection_status,
|
display_connection_status=display_connection_status,
|
||||||
url_params=json.dumps(url_params)
|
url_params=json.dumps(url_params),
|
||||||
|
key=queryToolShortcuts.get('keys'),
|
||||||
|
shortcuts=queryToolShortcuts.get('shortcuts'),
|
||||||
|
get_shortcut_text=get_text_representation_of_shortcut
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -28,14 +28,19 @@
|
||||||
<div id="btn-toolbar" class="pg-prop-btn-group bg-gray-2 border-gray-3" role="toolbar" aria-label="">
|
<div id="btn-toolbar" class="pg-prop-btn-group bg-gray-2 border-gray-3" role="toolbar" aria-label="">
|
||||||
<div class="btn-group" role="group" aria-label="">
|
<div class="btn-group" role="group" aria-label="">
|
||||||
<button id="btn-load-file" type="button" class="btn btn-default btn-load-file"
|
<button id="btn-load-file" type="button" class="btn btn-default btn-load-file"
|
||||||
title="{{ _('Open File') }}" accesskey="o" tabindex="0">
|
title="{{ _('Open File') }}{{ _(' (accesskey+{0})'.format(key.open_file.upper())) }}"
|
||||||
|
accesskey="{{key.open_file}}"
|
||||||
|
tabindex="0">
|
||||||
<i class="fa fa-folder-open-o" aria-hidden="true"></i>
|
<i class="fa fa-folder-open-o" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
<button id="btn-save" type="button" class="btn btn-default" title="{{ _('Save') }}" disabled>
|
<button id="btn-save" type="button" class="btn btn-default"
|
||||||
|
title="{{ _('Save') }}{{ _(' (accesskey+{0})'.format(key.save_file.upper())) }}"
|
||||||
|
accesskey="{{key.save_file}}"
|
||||||
|
disabled>
|
||||||
<i class="fa fa-floppy-o" aria-hidden="true" tabindex="0"></i>
|
<i class="fa fa-floppy-o" aria-hidden="true" tabindex="0"></i>
|
||||||
</button>
|
</button>
|
||||||
<button id="btn-file-menu-dropdown" type="button" class="btn btn-default dropdown-toggle"
|
<button id="btn-file-menu-dropdown" type="button" class="btn btn-default dropdown-toggle"
|
||||||
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" disabled accesskey="s"
|
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" disabled
|
||||||
tabindex="0">
|
tabindex="0">
|
||||||
<span class="caret"></span> <span class="sr-only">{{ _('Toggle Dropdown') }}</span>
|
<span class="caret"></span> <span class="sr-only">{{ _('Toggle Dropdown') }}</span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -57,7 +62,10 @@
|
||||||
<i class="fa fa-search" aria-hidden="true" tabindex="0"></i>
|
<i class="fa fa-search" aria-hidden="true" tabindex="0"></i>
|
||||||
</button>
|
</button>
|
||||||
<button id="btn-find-menu-dropdown" type="button" class="btn btn-default dropdown-toggle"
|
<button id="btn-find-menu-dropdown" type="button" class="btn btn-default dropdown-toggle"
|
||||||
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" accesskey="f" tabindex="0">
|
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"
|
||||||
|
title="{{ _('Find options') }}{{ _(' (accesskey+{0})'.format(key.find_options.upper())) }}"
|
||||||
|
accesskey="{{key.find_options}}"
|
||||||
|
tabindex="0">
|
||||||
<span class="caret"></span> <span class="sr-only">Toggle Dropdown</span>
|
<span class="caret"></span> <span class="sr-only">Toggle Dropdown</span>
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
|
@ -114,24 +122,30 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-group" role="group" aria-label="">
|
<div class="btn-group" role="group" aria-label="">
|
||||||
<button id="btn-copy-row" type="button" class="btn btn-default"
|
<button id="btn-copy-row" type="button" class="btn btn-default"
|
||||||
title="{{ _('Copy') }}" disabled accesskey="c" tabindex="0">
|
title="{{ _('Copy') }}{{ _(' (accesskey+{0})'.format(key.copy_row.upper())) }}"
|
||||||
|
accesskey="{{key.copy_row}}"
|
||||||
|
tabindex="0" disabled>
|
||||||
<i class="fa fa-files-o" aria-hidden="true"></i>
|
<i class="fa fa-files-o" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
<button id="btn-paste-row" type="button" class="btn btn-default"
|
<button id="btn-paste-row" type="button" class="btn btn-default"
|
||||||
title="{{ _('Paste Row') }}" disabled accesskey="p" tabindex="0">
|
title="{{ _('Paste') }}{{ _(' (accesskey+{0})'.format(key.paste_row.upper())) }}"
|
||||||
|
accesskey="{{key.paste_row}}"
|
||||||
|
tabindex="0" disabled>
|
||||||
<i class="fa fa-clipboard" aria-hidden="true"></i>
|
<i class="fa fa-clipboard" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-group" role="group" aria-label="">
|
<div class="btn-group" role="group" aria-label="">
|
||||||
<button id="btn-delete-row" type="button" class="btn btn-default"
|
<button id="btn-delete-row" type="button" class="btn btn-default"
|
||||||
title="{{ _('Delete Row(s)') }}" disabled accesskey="d" tabindex="0">
|
title="{{ _('Delete') }}{{ _(' (accesskey+{0})'.format(key.delete_row.upper())) }}"
|
||||||
|
accesskey="{{key.delete_row}}"
|
||||||
|
tabindex="0" disabled>
|
||||||
<i class="fa fa-trash" aria-hidden="true"></i>
|
<i class="fa fa-trash" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-group" role="group" aria-label="">
|
<div class="btn-group" role="group" aria-label="">
|
||||||
<button id="btn-edit-dropdown" type="button" class="btn btn-default dropdown-toggle"
|
<button id="btn-edit-dropdown" type="button" class="btn btn-default dropdown-toggle"
|
||||||
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"
|
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"
|
||||||
title="{{ _('Edit') }}" accesskey="e" tabindex="0">
|
title="{{ _('Edit') }}" tabindex="0">
|
||||||
<i class="fa fa-pencil-square-o" aria-hidden="true"></i>
|
<i class="fa fa-pencil-square-o" aria-hidden="true"></i>
|
||||||
<span class="caret"></span> <span class="sr-only">{{ _('Toggle Dropdown') }}</span>
|
<span class="caret"></span> <span class="sr-only">{{ _('Toggle Dropdown') }}</span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -166,11 +180,16 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-group" role="group" aria-label="">
|
<div class="btn-group" role="group" aria-label="">
|
||||||
<button id="btn-filter" type="button" class="btn btn-default"
|
<button id="btn-filter" type="button" class="btn btn-default"
|
||||||
title="{{ _('Filter') }}" disabled accesskey="i" tabindex="0">
|
title="{{ _('Filter') }}{{ _(' (accesskey+{0})'.format(key.filter_dialog.upper())) }}"
|
||||||
|
accesskey="{{key.filter_dialog}}"
|
||||||
|
tabindex="0" disabled>
|
||||||
<i class="fa fa-filter" aria-hidden="true"></i>
|
<i class="fa fa-filter" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
<button id="btn-filter-dropdown" type="button" class="btn btn-default dropdown-toggle"
|
<button id="btn-filter-dropdown" type="button" class="btn btn-default dropdown-toggle"
|
||||||
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" disabled tabindex="0">
|
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"
|
||||||
|
title="{{ _('Filter options') }}{{ _(' (accesskey+{0})'.format(key.filter_options.upper())) }}"
|
||||||
|
accesskey="{{key.filter_options}}"
|
||||||
|
disabled tabindex="0">
|
||||||
<span class="caret"></span> <span class="sr-only">{{ _('Toggle Dropdown') }}</span>
|
<span class="caret"></span> <span class="sr-only">{{ _('Toggle Dropdown') }}</span>
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu dropdown-menu-right">
|
<ul class="dropdown-menu dropdown-menu-right">
|
||||||
|
@ -183,36 +202,44 @@
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-group" role="group" aria-label="">
|
<div class="btn-group" role="group" aria-label="">
|
||||||
<select class="limit" style="height: 30px; width: 90px;" disabled accesskey="r" tabindex="0">
|
<select class="limit" style="height: 30px; width: 90px;" disabled
|
||||||
|
title="{{ _('Rows limit') }}{{ _(' (accesskey+{0})'.format(key.rows_limit.upper())) }}"
|
||||||
|
accesskey="{{key.rows_limit}}"
|
||||||
|
tabindex="0">
|
||||||
<option value="-1">{{ _('No limit') }}</option>
|
<option value="-1">{{ _('No limit') }}</option>
|
||||||
<option value="1000">{{ _('1000 rows') }}</option>
|
<option value="1000">{{ _('1000 rows') }}</option>
|
||||||
<option value="500">{{ _('500 rows') }}</option>
|
<option value="500">{{ _('500 rows') }}</option>
|
||||||
<option value="100">{{ _('100 rows') }}</option>
|
<option value="100">{{ _('100 rows') }}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="btn-group" role="group" aria-label="">
|
<div class="btn-group" role="group" aria-label="">
|
||||||
<button id="btn-flash" type="button" class="btn btn-default" style="width: 40px;"
|
<button id="btn-flash" type="button" class="btn btn-default" style="width: 40px;"
|
||||||
title="{{ _('Execute/Refresh (F5)') }}" tabindex="0">
|
title="{{ _('Execute/Refresh') }}{{ _(' ({0})'.format(get_shortcut_text(shortcuts.execute_query))) }}"
|
||||||
|
tabindex="0">
|
||||||
<i class="fa fa-bolt" aria-hidden="true"></i>
|
<i class="fa fa-bolt" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
<button id="btn-query-dropdown" type="button" class="btn btn-default dropdown-toggle"
|
<button id="btn-query-dropdown" type="button" class="btn btn-default dropdown-toggle"
|
||||||
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" accesskey="x" tabindex="0">
|
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"
|
||||||
|
accesskey="{{key.execute_options}}"
|
||||||
|
title="{{ _('Execute options') }}{{ _(' (accesskey+{0})'.format(key.execute_options.upper())) }}"
|
||||||
|
tabindex="0">
|
||||||
<span class="caret"></span> <span class="sr-only">{{ _('Toggle Dropdown') }}</span>
|
<span class="caret"></span> <span class="sr-only">{{ _('Toggle Dropdown') }}</span>
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu" role="menu">
|
<ul class="dropdown-menu" role="menu">
|
||||||
<li>
|
<li>
|
||||||
<a id="btn-flash-menu" href="#" tabindex="0">
|
<a id="btn-flash-menu" href="#" tabindex="0">
|
||||||
<span>{{ _('Execute/Refresh (F5)') }}</span>
|
<span>{{ _('Execute/Refresh') }}{{ _(' ({0})'.format(get_shortcut_text(shortcuts.execute_query))) }}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a id="btn-explain" href="#" tabindex="0">
|
<a id="btn-explain" href="#" tabindex="0">
|
||||||
<span>{{ _('Explain (F7)') }}</span>
|
<span>{{ _('Explain') }}{{ _(' ({0})'.format(get_shortcut_text(shortcuts.explain_query))) }}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a id="btn-explain-analyze" href="#" tabindex="0">
|
<a id="btn-explain-analyze" href="#" tabindex="0">
|
||||||
<span>{{ _('Explain Analyze (Shift+F7)') }}</span>
|
<span>{{ _('Explain Analyze') }}{{ _(' ({0})'.format(get_shortcut_text(shortcuts.explain_analyze_query))) }}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="divider"></li>
|
<li class="divider"></li>
|
||||||
|
@ -259,15 +286,19 @@
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<button id="btn-cancel-query" type="button" class="btn btn-default" title="{{ _('Cancel query') }}"
|
<button id="btn-cancel-query" type="button" class="btn btn-default"
|
||||||
disabled accesskey="q" tabindex="0">
|
title="{{ _('Cancel query') }}{{ _(' (accesskey+{0})'.format(key.cancel_query.upper())) }}"
|
||||||
|
accesskey="{{key.cancel_query}}"
|
||||||
|
tabindex="0" disabled >
|
||||||
<i class="fa fa-stop" aria-hidden="true"></i>
|
<i class="fa fa-stop" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-group" role="group" aria-label="">
|
<div class="btn-group" role="group" aria-label="">
|
||||||
<button id="btn-clear-dropdown" type="button" class="btn btn-default dropdown-toggle"
|
<button id="btn-clear-dropdown" type="button" class="btn btn-default dropdown-toggle"
|
||||||
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"
|
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"
|
||||||
title="{{ _('Clear') }}" accesskey="l" tabindex="0">
|
title="{{ _('Clear') }}{{ _(' (accesskey+{0})'.format(key.clear_options.upper())) }}"
|
||||||
|
accesskey="{{key.clear_options}}"
|
||||||
|
tabindex="0">
|
||||||
<i class="fa fa-eraser" aria-hidden="true"></i>
|
<i class="fa fa-eraser" aria-hidden="true"></i>
|
||||||
<span class="caret"></span> <span class="sr-only">{{ _('Toggle Dropdown') }}</span>
|
<span class="caret"></span> <span class="sr-only">{{ _('Toggle Dropdown') }}</span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -284,7 +315,8 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-group" role="group" aria-label="">
|
<div class="btn-group" role="group" aria-label="">
|
||||||
<button id="btn-download" type="button" class="btn btn-default"
|
<button id="btn-download" type="button" class="btn btn-default"
|
||||||
title="{{ _('Download as CSV (F8)') }}" accesskey="v" tabindex="0">
|
title="{{ _('Download as CSV') }}{{ _(' ({0})'.format(get_shortcut_text(shortcuts.download_csv))) }}"
|
||||||
|
tabindex="0">
|
||||||
<i class="fa fa-download" aria-hidden="true"></i>
|
<i class="fa fa-download" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -293,14 +325,15 @@
|
||||||
<div class="connection_status_wrapper">
|
<div class="connection_status_wrapper">
|
||||||
{% if display_connection_status %}
|
{% if display_connection_status %}
|
||||||
<div style="display: inline-block;"
|
<div style="display: inline-block;"
|
||||||
title="{{ _('Connection status (click for details) (<accesskey>+T)') }}">
|
title="{{ _('Connection status (click for details) (accesskey+{0})'.format(key.conn_status.upper())) }}">
|
||||||
<div class="connection_status" data-container="body"
|
<div class="connection_status" data-container="body"
|
||||||
data-toggle="popover" data-placement="bottom"
|
data-toggle="popover" data-placement="bottom"
|
||||||
data-content=""
|
data-content=""
|
||||||
data-panel-visible="visible"
|
data-panel-visible="visible"
|
||||||
accesskey="t" tabindex="0">
|
accesskey="{{key.conn_status}}"
|
||||||
|
tabindex="0">
|
||||||
<i class="fa-custom fa-query-tool-disconnected" aria-hidden="true"
|
<i class="fa-custom fa-query-tool-disconnected" aria-hidden="true"
|
||||||
title="{{ _('Connection status (click for details) (<accesskey>+T)') }}">
|
title="{{ _('Connection status (click for details) (accesskey+{0})'.format(key.conn_status.upper())) }}">
|
||||||
</i>
|
</i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -20,7 +20,9 @@ from flask_babel import gettext
|
||||||
from flask_security import login_required
|
from flask_security import login_required
|
||||||
from werkzeug.useragents import UserAgent
|
from werkzeug.useragents import UserAgent
|
||||||
|
|
||||||
from pgadmin.utils import PgAdminModule
|
from pgadmin.utils import PgAdminModule, \
|
||||||
|
SHORTCUT_FIELDS as shortcut_fields, \
|
||||||
|
ACCESSKEY_FIELDS as accesskey_fields
|
||||||
from pgadmin.utils.ajax import bad_request
|
from pgadmin.utils.ajax import bad_request
|
||||||
from pgadmin.utils.ajax import make_json_response, \
|
from pgadmin.utils.ajax import make_json_response, \
|
||||||
internal_server_error
|
internal_server_error
|
||||||
|
@ -73,38 +75,6 @@ class DebuggerModule(PgAdminModule):
|
||||||
'will be opened in a new browser tab.')
|
'will be opened in a new browser tab.')
|
||||||
)
|
)
|
||||||
|
|
||||||
# Shortcut configuration for Accesskey
|
|
||||||
accesskey_fields = [
|
|
||||||
{
|
|
||||||
'name': 'key',
|
|
||||||
'type': 'keyCode',
|
|
||||||
'label': gettext('Key')
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
shortcut_fields = [
|
|
||||||
{
|
|
||||||
'name': 'key',
|
|
||||||
'type': 'keyCode',
|
|
||||||
'label': gettext('Key')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'name': 'shift',
|
|
||||||
'type': 'checkbox',
|
|
||||||
'label': gettext('Shift')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'name': 'control',
|
|
||||||
'type': 'checkbox',
|
|
||||||
'label': gettext('Ctrl')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'name': 'alt',
|
|
||||||
'type': 'checkbox',
|
|
||||||
'label': gettext('Alt/Option')
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
self.preference.register(
|
self.preference.register(
|
||||||
'keyboard_shortcuts', 'btn_start',
|
'keyboard_shortcuts', 'btn_start',
|
||||||
gettext('Accesskey (Continue/Start)'), 'keyboardshortcut',
|
gettext('Accesskey (Continue/Start)'), 'keyboardshortcut',
|
||||||
|
|
|
@ -36,6 +36,8 @@ from pgadmin.utils.driver import get_driver
|
||||||
from pgadmin.utils.menu import MenuItem
|
from pgadmin.utils.menu import MenuItem
|
||||||
from pgadmin.utils.exception import ConnectionLost
|
from pgadmin.utils.exception import ConnectionLost
|
||||||
from pgadmin.utils.sqlautocomplete.autocomplete import SQLAutoComplete
|
from pgadmin.utils.sqlautocomplete.autocomplete import SQLAutoComplete
|
||||||
|
from pgadmin.tools.sqleditor.utils.query_tool_preferences import \
|
||||||
|
RegisterQueryToolPreferences
|
||||||
|
|
||||||
MODULE_NAME = 'sqleditor'
|
MODULE_NAME = 'sqleditor'
|
||||||
|
|
||||||
|
@ -106,247 +108,7 @@ class SqlEditorModule(PgAdminModule):
|
||||||
]
|
]
|
||||||
|
|
||||||
def register_preferences(self):
|
def register_preferences(self):
|
||||||
self.info_notifier_timeout = self.preference.register(
|
RegisterQueryToolPreferences(self)
|
||||||
'display', 'info_notifier_timeout',
|
|
||||||
gettext("Query info notifier timeout"), 'integer', 5,
|
|
||||||
category_label=gettext('Display'),
|
|
||||||
min_val=-1,
|
|
||||||
max_val=999999,
|
|
||||||
help_str=gettext(
|
|
||||||
'The length of time to display the query info notifier after '
|
|
||||||
'execution has completed. A value of -1 disables the notifier'
|
|
||||||
' and a value of 0 displays it until clicked. Values greater'
|
|
||||||
' than 0 display the notifier for the number of seconds'
|
|
||||||
' specified.'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
self.open_in_new_tab = self.preference.register(
|
|
||||||
'display', 'new_browser_tab',
|
|
||||||
gettext("Open in new browser tab"), 'boolean', False,
|
|
||||||
category_label=gettext('Display'),
|
|
||||||
help_str=gettext('If set to True, the Query Tool '
|
|
||||||
'will be opened in a new browser tab.')
|
|
||||||
)
|
|
||||||
|
|
||||||
self.explain_verbose = self.preference.register(
|
|
||||||
'Explain', 'explain_verbose',
|
|
||||||
gettext("Verbose output?"), 'boolean', False,
|
|
||||||
category_label=gettext('Explain')
|
|
||||||
)
|
|
||||||
|
|
||||||
self.explain_costs = self.preference.register(
|
|
||||||
'Explain', 'explain_costs',
|
|
||||||
gettext("Show costs?"), 'boolean', False,
|
|
||||||
category_label=gettext('Explain')
|
|
||||||
)
|
|
||||||
|
|
||||||
self.explain_buffers = self.preference.register(
|
|
||||||
'Explain', 'explain_buffers',
|
|
||||||
gettext("Show buffers?"), 'boolean', False,
|
|
||||||
category_label=gettext('Explain')
|
|
||||||
)
|
|
||||||
|
|
||||||
self.explain_timing = self.preference.register(
|
|
||||||
'Explain', 'explain_timing',
|
|
||||||
gettext("Show timing?"), 'boolean', False,
|
|
||||||
category_label=gettext('Explain')
|
|
||||||
)
|
|
||||||
|
|
||||||
self.auto_commit = self.preference.register(
|
|
||||||
'Options', 'auto_commit',
|
|
||||||
gettext("Auto commit?"), 'boolean', True,
|
|
||||||
category_label=gettext('Options')
|
|
||||||
)
|
|
||||||
|
|
||||||
self.auto_rollback = self.preference.register(
|
|
||||||
'Options', 'auto_rollback',
|
|
||||||
gettext("Auto rollback?"), 'boolean', False,
|
|
||||||
category_label=gettext('Options')
|
|
||||||
)
|
|
||||||
|
|
||||||
self.sql_font_size = self.preference.register(
|
|
||||||
'Options', 'sql_font_size',
|
|
||||||
gettext("Font size"), 'numeric', '1',
|
|
||||||
min_val=0.1,
|
|
||||||
max_val=10,
|
|
||||||
category_label=gettext('Display'),
|
|
||||||
help_str=gettext(
|
|
||||||
'The font size to use for the SQL text boxes and editors. '
|
|
||||||
'The value specified is in "em" units, in which 1 is the '
|
|
||||||
'default relative font size. For example, to increase the '
|
|
||||||
'font size by 20 percent use a value of 1.2, or to reduce '
|
|
||||||
'by 20 percent, use a value of 0.8. Minimum 0.1, maximum 10.'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
self.tab_size = self.preference.register(
|
|
||||||
'Options', 'tab_size',
|
|
||||||
gettext("Tab size"), 'integer', 4,
|
|
||||||
min_val=2,
|
|
||||||
max_val=8,
|
|
||||||
category_label=gettext('Options'),
|
|
||||||
help_str=gettext(
|
|
||||||
'The number of spaces per tab. Minimum 2, maximum 8.'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
self.use_spaces = self.preference.register(
|
|
||||||
'Options', 'use_spaces',
|
|
||||||
gettext("Use spaces?"), 'boolean', False,
|
|
||||||
category_label=gettext('Options'),
|
|
||||||
help_str=gettext(
|
|
||||||
'Specifies whether or not to insert spaces instead of tabs '
|
|
||||||
'when the tab key or auto-indent are used.'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
self.wrap_code = self.preference.register(
|
|
||||||
'Options', 'wrap_code',
|
|
||||||
gettext("Line wrapping?"), 'boolean', False,
|
|
||||||
category_label=gettext('Options'),
|
|
||||||
help_str=gettext(
|
|
||||||
'Specifies whether or not to wrap SQL code in the editor.'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
self.insert_pair_brackets = self.preference.register(
|
|
||||||
'Options', 'insert_pair_brackets',
|
|
||||||
gettext("Insert bracket pairs?"), 'boolean', True,
|
|
||||||
category_label=gettext('Options'),
|
|
||||||
help_str=gettext(
|
|
||||||
'Specifies whether or not to insert paired brackets in the '
|
|
||||||
'editor.'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
self.brace_matching = self.preference.register(
|
|
||||||
'Options', 'brace_matching',
|
|
||||||
gettext("Brace matching?"), 'boolean', True,
|
|
||||||
category_label=gettext('Options'),
|
|
||||||
help_str=gettext(
|
|
||||||
'Specifies whether or not to highlight matched braces '
|
|
||||||
'in the editor.'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
self.show_prompt_save_query_changes = self.preference.register(
|
|
||||||
'Options', 'prompt_save_query_changes',
|
|
||||||
gettext("Prompt to save unsaved query changes?"), 'boolean', True,
|
|
||||||
category_label=gettext('Options'),
|
|
||||||
help_str=gettext(
|
|
||||||
'Specifies whether or not to prompt user to save unsaved '
|
|
||||||
'query on query tool exit.'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
self.show_prompt_save_data_changes = self.preference.register(
|
|
||||||
'Options', 'prompt_save_data_changes',
|
|
||||||
gettext("Prompt to save unsaved data changes?"), 'boolean', True,
|
|
||||||
category_label=gettext('Options'),
|
|
||||||
help_str=gettext(
|
|
||||||
'Specifies whether or not to prompt user to save unsaved '
|
|
||||||
'data on data grid exit.'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
self.csv_quoting = self.preference.register(
|
|
||||||
'CSV_output', 'csv_quoting',
|
|
||||||
gettext("CSV quoting"), 'options', 'strings',
|
|
||||||
category_label=gettext('CSV Output'),
|
|
||||||
options=[{'label': 'None', 'value': 'none'},
|
|
||||||
{'label': 'All', 'value': 'all'},
|
|
||||||
{'label': 'Strings', 'value': 'strings'}],
|
|
||||||
select2={
|
|
||||||
'allowClear': False,
|
|
||||||
'tags': False
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
self.csv_quote_char = self.preference.register(
|
|
||||||
'CSV_output', 'csv_quote_char',
|
|
||||||
gettext("CSV quote character"), 'options', '"',
|
|
||||||
category_label=gettext('CSV Output'),
|
|
||||||
options=[{'label': '"', 'value': '"'},
|
|
||||||
{'label': '\'', 'value': '\''}],
|
|
||||||
select2={
|
|
||||||
'allowClear': False,
|
|
||||||
'tags': True
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
self.csv_field_separator = self.preference.register(
|
|
||||||
'CSV_output', 'csv_field_separator',
|
|
||||||
gettext("CSV field separator"), 'options', ',',
|
|
||||||
category_label=gettext('CSV output'),
|
|
||||||
options=[{'label': ';', 'value': ';'},
|
|
||||||
{'label': ',', 'value': ','},
|
|
||||||
{'label': '|', 'value': '|'},
|
|
||||||
{'label': 'Tab', 'value': '\t'}],
|
|
||||||
select2={
|
|
||||||
'allowClear': False,
|
|
||||||
'tags': True
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
self.results_grid_quoting = self.preference.register(
|
|
||||||
'Results_grid', 'results_grid_quoting',
|
|
||||||
gettext("Result copy quoting"), 'options', 'strings',
|
|
||||||
category_label=gettext('Results grid'),
|
|
||||||
options=[{'label': 'None', 'value': 'none'},
|
|
||||||
{'label': 'All', 'value': 'all'},
|
|
||||||
{'label': 'Strings', 'value': 'strings'}],
|
|
||||||
select2={
|
|
||||||
'allowClear': False,
|
|
||||||
'tags': False
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
self.results_grid_quote_char = self.preference.register(
|
|
||||||
'Results_grid', 'results_grid_quote_char',
|
|
||||||
gettext("Result copy quote character"), 'options', '"',
|
|
||||||
category_label=gettext('Results grid'),
|
|
||||||
options=[{'label': '"', 'value': '"'},
|
|
||||||
{'label': '\'', 'value': '\''}],
|
|
||||||
select2={
|
|
||||||
'allowClear': False,
|
|
||||||
'tags': True
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
self.results_grid_field_separator = self.preference.register(
|
|
||||||
'Results_grid', 'results_grid_field_separator',
|
|
||||||
gettext("Result copy field separator"), 'options', '\t',
|
|
||||||
category_label=gettext('Results grid'),
|
|
||||||
options=[{'label': ';', 'value': ';'},
|
|
||||||
{'label': ',', 'value': ','},
|
|
||||||
{'label': '|', 'value': '|'},
|
|
||||||
{'label': 'Tab', 'value': '\t'}],
|
|
||||||
select2={
|
|
||||||
'allowClear': False,
|
|
||||||
'tags': True
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
self.display_connection_status = self.preference.register(
|
|
||||||
'display', 'connection_status',
|
|
||||||
gettext("Connection status"), 'boolean', True,
|
|
||||||
category_label=gettext('Display'),
|
|
||||||
help_str=gettext('If set to True, the Query Tool '
|
|
||||||
'will monitor and display the connection and '
|
|
||||||
'transaction status.')
|
|
||||||
)
|
|
||||||
|
|
||||||
self.connection_status = self.preference.register(
|
|
||||||
'display', 'connection_status_fetch_time',
|
|
||||||
gettext("Connection status refresh rate"), 'integer', 2,
|
|
||||||
min_val=1, max_val=600,
|
|
||||||
category_label=gettext('Display'),
|
|
||||||
help_str=gettext(
|
|
||||||
'The number of seconds between connection/transaction '
|
|
||||||
'status polls.'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
blueprint = SqlEditorModule(MODULE_NAME, __name__, static_url_path='/static')
|
blueprint = SqlEditorModule(MODULE_NAME, __name__, static_url_path='/static')
|
||||||
|
|
|
@ -114,6 +114,9 @@ define('tools.querytool', [
|
||||||
$('.editor-title').text(_.unescape(self.editor_title));
|
$('.editor-title').text(_.unescape(self.editor_title));
|
||||||
self.checkConnectionStatus();
|
self.checkConnectionStatus();
|
||||||
|
|
||||||
|
// Fetch and assign the shortcuts to current instance
|
||||||
|
self.keyboardShortcutConfig = queryToolActions.getKeyboardShortcuts(self);
|
||||||
|
|
||||||
self.filter_obj = CodeMirror.fromTextArea(filter.get(0), {
|
self.filter_obj = CodeMirror.fromTextArea(filter.get(0), {
|
||||||
tabindex: '0',
|
tabindex: '0',
|
||||||
lineNumbers: true,
|
lineNumbers: true,
|
||||||
|
@ -1720,7 +1723,7 @@ define('tools.querytool', [
|
||||||
keyAction: function(event) {
|
keyAction: function(event) {
|
||||||
var panel_id, self = this;
|
var panel_id, self = this;
|
||||||
panel_id = keyboardShortcuts.processEventQueryTool(
|
panel_id = keyboardShortcuts.processEventQueryTool(
|
||||||
this.handler, queryToolActions, event
|
this.handler, this.keyboardShortcutConfig, queryToolActions, event
|
||||||
);
|
);
|
||||||
|
|
||||||
// If it return panel id then focus it
|
// If it return panel id then focus it
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
##########################################################################
|
||||||
|
#
|
||||||
|
# pgAdmin 4 - PostgreSQL Tools
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||||
|
# This software is released under the PostgreSQL Licence
|
||||||
|
#
|
||||||
|
##########################################################################
|
||||||
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
|
from pgadmin.tools.sqleditor.utils.query_tool_preferences import \
|
||||||
|
get_text_representation_of_shortcut
|
||||||
|
|
||||||
|
|
||||||
|
class TestQueryToolPreference(BaseTestGenerator):
|
||||||
|
"""
|
||||||
|
Ensures that we are able to fetch preferences properly
|
||||||
|
"""
|
||||||
|
scenarios = [
|
||||||
|
('Check text representation of a valid shortcuts', dict(
|
||||||
|
fetch_pref=True,
|
||||||
|
sample_shortcut=dict(
|
||||||
|
alt=False,
|
||||||
|
shift=False,
|
||||||
|
control=False,
|
||||||
|
key=dict(
|
||||||
|
char='a',
|
||||||
|
keyCode=65
|
||||||
|
)
|
||||||
|
),
|
||||||
|
expected_result='a'
|
||||||
|
)),
|
||||||
|
|
||||||
|
('Check text representation of a valid shortcuts', dict(
|
||||||
|
fetch_pref=True,
|
||||||
|
sample_shortcut=dict(
|
||||||
|
alt=True,
|
||||||
|
shift=False,
|
||||||
|
control=False,
|
||||||
|
key=dict(
|
||||||
|
char='a',
|
||||||
|
keyCode=65
|
||||||
|
)
|
||||||
|
),
|
||||||
|
expected_result='Alt+a'
|
||||||
|
)),
|
||||||
|
|
||||||
|
('Check text representation of a valid shortcuts', dict(
|
||||||
|
fetch_pref=True,
|
||||||
|
sample_shortcut=dict(
|
||||||
|
alt=True,
|
||||||
|
shift=True,
|
||||||
|
control=True,
|
||||||
|
key=dict(
|
||||||
|
char='a',
|
||||||
|
keyCode=65
|
||||||
|
)
|
||||||
|
),
|
||||||
|
expected_result='Alt+Shift+Ctrl+a'
|
||||||
|
)),
|
||||||
|
|
||||||
|
('Check text representation of a valid shortcuts', dict(
|
||||||
|
fetch_pref=True,
|
||||||
|
sample_shortcut=dict(
|
||||||
|
alt=False,
|
||||||
|
shift=True,
|
||||||
|
control=False,
|
||||||
|
key=dict(
|
||||||
|
char='a',
|
||||||
|
keyCode=65
|
||||||
|
)
|
||||||
|
),
|
||||||
|
expected_result='Shift+a'
|
||||||
|
)),
|
||||||
|
|
||||||
|
('Check text representation of a valid shortcuts', dict(
|
||||||
|
fetch_pref=True,
|
||||||
|
sample_shortcut=dict(
|
||||||
|
alt=True,
|
||||||
|
shift=True,
|
||||||
|
control=False,
|
||||||
|
key=dict(
|
||||||
|
char='a',
|
||||||
|
keyCode=65
|
||||||
|
)
|
||||||
|
),
|
||||||
|
expected_result='Alt+Shift+a'
|
||||||
|
)),
|
||||||
|
|
||||||
|
('Check text representation of a invalid shortcuts', dict(
|
||||||
|
fetch_pref=True,
|
||||||
|
sample_shortcut=None,
|
||||||
|
expected_result=''
|
||||||
|
))
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
def runTest(self):
|
||||||
|
"""Check correct function is called to handle to run query."""
|
||||||
|
result = get_text_representation_of_shortcut(self.sample_shortcut)
|
||||||
|
self.assertEquals(result, self.expected_result)
|
|
@ -0,0 +1,653 @@
|
||||||
|
##########################################################################
|
||||||
|
#
|
||||||
|
# pgAdmin 4 - PostgreSQL Tools
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||||
|
# This software is released under the PostgreSQL Licence
|
||||||
|
#
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
"""Register preferences for query tool"""
|
||||||
|
from flask_babel import gettext
|
||||||
|
from pgadmin.utils import SHORTCUT_FIELDS as shortcut_fields, \
|
||||||
|
ACCESSKEY_FIELDS as accesskey_fields
|
||||||
|
from pgadmin.utils.preferences import Preferences
|
||||||
|
|
||||||
|
|
||||||
|
def RegisterQueryToolPreferences(self):
|
||||||
|
self.info_notifier_timeout = self.preference.register(
|
||||||
|
'display', 'info_notifier_timeout',
|
||||||
|
gettext("Query info notifier timeout"), 'integer', 5,
|
||||||
|
category_label=gettext('Display'),
|
||||||
|
min_val=-1,
|
||||||
|
max_val=999999,
|
||||||
|
help_str=gettext(
|
||||||
|
'The length of time to display the query info notifier after '
|
||||||
|
'execution has completed. A value of -1 disables the notifier'
|
||||||
|
' and a value of 0 displays it until clicked. Values greater'
|
||||||
|
' than 0 display the notifier for the number of seconds'
|
||||||
|
' specified.'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.open_in_new_tab = self.preference.register(
|
||||||
|
'display', 'new_browser_tab',
|
||||||
|
gettext("Open in new browser tab"), 'boolean', False,
|
||||||
|
category_label=gettext('Display'),
|
||||||
|
help_str=gettext('If set to True, the Query Tool '
|
||||||
|
'will be opened in a new browser tab.')
|
||||||
|
)
|
||||||
|
|
||||||
|
self.explain_verbose = self.preference.register(
|
||||||
|
'Explain', 'explain_verbose',
|
||||||
|
gettext("Verbose output?"), 'boolean', False,
|
||||||
|
category_label=gettext('Explain')
|
||||||
|
)
|
||||||
|
|
||||||
|
self.explain_costs = self.preference.register(
|
||||||
|
'Explain', 'explain_costs',
|
||||||
|
gettext("Show costs?"), 'boolean', False,
|
||||||
|
category_label=gettext('Explain')
|
||||||
|
)
|
||||||
|
|
||||||
|
self.explain_buffers = self.preference.register(
|
||||||
|
'Explain', 'explain_buffers',
|
||||||
|
gettext("Show buffers?"), 'boolean', False,
|
||||||
|
category_label=gettext('Explain')
|
||||||
|
)
|
||||||
|
|
||||||
|
self.explain_timing = self.preference.register(
|
||||||
|
'Explain', 'explain_timing',
|
||||||
|
gettext("Show timing?"), 'boolean', False,
|
||||||
|
category_label=gettext('Explain')
|
||||||
|
)
|
||||||
|
|
||||||
|
self.auto_commit = self.preference.register(
|
||||||
|
'Options', 'auto_commit',
|
||||||
|
gettext("Auto commit?"), 'boolean', True,
|
||||||
|
category_label=gettext('Options')
|
||||||
|
)
|
||||||
|
|
||||||
|
self.auto_rollback = self.preference.register(
|
||||||
|
'Options', 'auto_rollback',
|
||||||
|
gettext("Auto rollback?"), 'boolean', False,
|
||||||
|
category_label=gettext('Options')
|
||||||
|
)
|
||||||
|
|
||||||
|
self.sql_font_size = self.preference.register(
|
||||||
|
'Options', 'sql_font_size',
|
||||||
|
gettext("Font size"), 'numeric', '1',
|
||||||
|
min_val=0.1,
|
||||||
|
max_val=10,
|
||||||
|
category_label=gettext('Display'),
|
||||||
|
help_str=gettext(
|
||||||
|
'The font size to use for the SQL text boxes and editors. '
|
||||||
|
'The value specified is in "em" units, in which 1 is the '
|
||||||
|
'default relative font size. For example, to increase the '
|
||||||
|
'font size by 20 percent use a value of 1.2, or to reduce '
|
||||||
|
'by 20 percent, use a value of 0.8. Minimum 0.1, maximum 10.'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.tab_size = self.preference.register(
|
||||||
|
'Options', 'tab_size',
|
||||||
|
gettext("Tab size"), 'integer', 4,
|
||||||
|
min_val=2,
|
||||||
|
max_val=8,
|
||||||
|
category_label=gettext('Options'),
|
||||||
|
help_str=gettext(
|
||||||
|
'The number of spaces per tab. Minimum 2, maximum 8.'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.use_spaces = self.preference.register(
|
||||||
|
'Options', 'use_spaces',
|
||||||
|
gettext("Use spaces?"), 'boolean', False,
|
||||||
|
category_label=gettext('Options'),
|
||||||
|
help_str=gettext(
|
||||||
|
'Specifies whether or not to insert spaces instead of tabs '
|
||||||
|
'when the tab key or auto-indent are used.'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.wrap_code = self.preference.register(
|
||||||
|
'Options', 'wrap_code',
|
||||||
|
gettext("Line wrapping?"), 'boolean', False,
|
||||||
|
category_label=gettext('Options'),
|
||||||
|
help_str=gettext(
|
||||||
|
'Specifies whether or not to wrap SQL code in the editor.'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.insert_pair_brackets = self.preference.register(
|
||||||
|
'Options', 'insert_pair_brackets',
|
||||||
|
gettext("Insert bracket pairs?"), 'boolean', True,
|
||||||
|
category_label=gettext('Options'),
|
||||||
|
help_str=gettext(
|
||||||
|
'Specifies whether or not to insert paired brackets in the '
|
||||||
|
'editor.'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.brace_matching = self.preference.register(
|
||||||
|
'Options', 'brace_matching',
|
||||||
|
gettext("Brace matching?"), 'boolean', True,
|
||||||
|
category_label=gettext('Options'),
|
||||||
|
help_str=gettext(
|
||||||
|
'Specifies whether or not to highlight matched braces '
|
||||||
|
'in the editor.'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.show_prompt_save_query_changes = self.preference.register(
|
||||||
|
'Options', 'prompt_save_query_changes',
|
||||||
|
gettext("Prompt to save unsaved query changes?"), 'boolean', True,
|
||||||
|
category_label=gettext('Options'),
|
||||||
|
help_str=gettext(
|
||||||
|
'Specifies whether or not to prompt user to save unsaved '
|
||||||
|
'query on query tool exit.'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.show_prompt_save_data_changes = self.preference.register(
|
||||||
|
'Options', 'prompt_save_data_changes',
|
||||||
|
gettext("Prompt to save unsaved data changes?"), 'boolean', True,
|
||||||
|
category_label=gettext('Options'),
|
||||||
|
help_str=gettext(
|
||||||
|
'Specifies whether or not to prompt user to save unsaved '
|
||||||
|
'data on data grid exit.'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.csv_quoting = self.preference.register(
|
||||||
|
'CSV_output', 'csv_quoting',
|
||||||
|
gettext("CSV quoting"), 'options', 'strings',
|
||||||
|
category_label=gettext('CSV Output'),
|
||||||
|
options=[{'label': 'None', 'value': 'none'},
|
||||||
|
{'label': 'All', 'value': 'all'},
|
||||||
|
{'label': 'Strings', 'value': 'strings'}],
|
||||||
|
select2={
|
||||||
|
'allowClear': False,
|
||||||
|
'tags': False
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
self.csv_quote_char = self.preference.register(
|
||||||
|
'CSV_output', 'csv_quote_char',
|
||||||
|
gettext("CSV quote character"), 'options', '"',
|
||||||
|
category_label=gettext('CSV Output'),
|
||||||
|
options=[{'label': '"', 'value': '"'},
|
||||||
|
{'label': '\'', 'value': '\''}],
|
||||||
|
select2={
|
||||||
|
'allowClear': False,
|
||||||
|
'tags': True
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
self.csv_field_separator = self.preference.register(
|
||||||
|
'CSV_output', 'csv_field_separator',
|
||||||
|
gettext("CSV field separator"), 'options', ',',
|
||||||
|
category_label=gettext('CSV output'),
|
||||||
|
options=[{'label': ';', 'value': ';'},
|
||||||
|
{'label': ',', 'value': ','},
|
||||||
|
{'label': '|', 'value': '|'},
|
||||||
|
{'label': 'Tab', 'value': '\t'}],
|
||||||
|
select2={
|
||||||
|
'allowClear': False,
|
||||||
|
'tags': True
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
self.results_grid_quoting = self.preference.register(
|
||||||
|
'Results_grid', 'results_grid_quoting',
|
||||||
|
gettext("Result copy quoting"), 'options', 'strings',
|
||||||
|
category_label=gettext('Results grid'),
|
||||||
|
options=[{'label': 'None', 'value': 'none'},
|
||||||
|
{'label': 'All', 'value': 'all'},
|
||||||
|
{'label': 'Strings', 'value': 'strings'}],
|
||||||
|
select2={
|
||||||
|
'allowClear': False,
|
||||||
|
'tags': False
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
self.results_grid_quote_char = self.preference.register(
|
||||||
|
'Results_grid', 'results_grid_quote_char',
|
||||||
|
gettext("Result copy quote character"), 'options', '"',
|
||||||
|
category_label=gettext('Results grid'),
|
||||||
|
options=[{'label': '"', 'value': '"'},
|
||||||
|
{'label': '\'', 'value': '\''}],
|
||||||
|
select2={
|
||||||
|
'allowClear': False,
|
||||||
|
'tags': True
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
self.results_grid_field_separator = self.preference.register(
|
||||||
|
'Results_grid', 'results_grid_field_separator',
|
||||||
|
gettext("Result copy field separator"), 'options', '\t',
|
||||||
|
category_label=gettext('Results grid'),
|
||||||
|
options=[{'label': ';', 'value': ';'},
|
||||||
|
{'label': ',', 'value': ','},
|
||||||
|
{'label': '|', 'value': '|'},
|
||||||
|
{'label': 'Tab', 'value': '\t'}],
|
||||||
|
select2={
|
||||||
|
'allowClear': False,
|
||||||
|
'tags': True
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
self.display_connection_status = self.preference.register(
|
||||||
|
'display', 'connection_status',
|
||||||
|
gettext("Connection status"), 'boolean', True,
|
||||||
|
category_label=gettext('Display'),
|
||||||
|
help_str=gettext('If set to True, the Query Tool '
|
||||||
|
'will monitor and display the connection and '
|
||||||
|
'transaction status.')
|
||||||
|
)
|
||||||
|
|
||||||
|
self.connection_status = self.preference.register(
|
||||||
|
'display', 'connection_status_fetch_time',
|
||||||
|
gettext("Connection status refresh rate"), 'integer', 2,
|
||||||
|
min_val=1, max_val=600,
|
||||||
|
category_label=gettext('Display'),
|
||||||
|
help_str=gettext(
|
||||||
|
'The number of seconds between connection/transaction '
|
||||||
|
'status polls.'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.preference.register(
|
||||||
|
'keyboard_shortcuts',
|
||||||
|
'execute_query',
|
||||||
|
gettext('Execute query'),
|
||||||
|
'keyboardshortcut',
|
||||||
|
{
|
||||||
|
'alt': False,
|
||||||
|
'shift': False,
|
||||||
|
'control': False,
|
||||||
|
'key': {
|
||||||
|
'key_code': 116,
|
||||||
|
'char': 'F5'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
category_label=gettext('Keyboard shortcuts'),
|
||||||
|
fields=shortcut_fields
|
||||||
|
)
|
||||||
|
|
||||||
|
self.preference.register(
|
||||||
|
'keyboard_shortcuts',
|
||||||
|
'explain_query',
|
||||||
|
gettext('EXPLAIN query'),
|
||||||
|
'keyboardshortcut',
|
||||||
|
{
|
||||||
|
'alt': False,
|
||||||
|
'shift': False,
|
||||||
|
'control': False,
|
||||||
|
'key': {
|
||||||
|
'key_code': 118,
|
||||||
|
'char': 'F7'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
category_label=gettext('Keyboard shortcuts'),
|
||||||
|
fields=shortcut_fields
|
||||||
|
)
|
||||||
|
|
||||||
|
self.preference.register(
|
||||||
|
'keyboard_shortcuts',
|
||||||
|
'explain_analyze_query',
|
||||||
|
gettext('EXPLAIN ANALYZE query'),
|
||||||
|
'keyboardshortcut',
|
||||||
|
{
|
||||||
|
'alt': False,
|
||||||
|
'shift': True,
|
||||||
|
'control': False,
|
||||||
|
'key': {
|
||||||
|
'key_code': 118,
|
||||||
|
'char': 'F7'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
category_label=gettext('Keyboard shortcuts'),
|
||||||
|
fields=shortcut_fields
|
||||||
|
)
|
||||||
|
|
||||||
|
self.preference.register(
|
||||||
|
'keyboard_shortcuts',
|
||||||
|
'download_csv',
|
||||||
|
gettext('Download CSV'),
|
||||||
|
'keyboardshortcut',
|
||||||
|
{
|
||||||
|
'alt': False,
|
||||||
|
'shift': False,
|
||||||
|
'control': False,
|
||||||
|
'key': {
|
||||||
|
'key_code': 119,
|
||||||
|
'char': 'F8'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
category_label=gettext('Keyboard shortcuts'),
|
||||||
|
fields=shortcut_fields
|
||||||
|
)
|
||||||
|
|
||||||
|
self.preference.register(
|
||||||
|
'keyboard_shortcuts',
|
||||||
|
'move_previous',
|
||||||
|
gettext('Previous tab'),
|
||||||
|
'keyboardshortcut',
|
||||||
|
{
|
||||||
|
'alt': True,
|
||||||
|
'shift': True,
|
||||||
|
'control': False,
|
||||||
|
'key': {
|
||||||
|
'key_code': 37,
|
||||||
|
'char': 'ArrowLeft'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
category_label=gettext('Keyboard shortcuts'),
|
||||||
|
fields=shortcut_fields
|
||||||
|
)
|
||||||
|
|
||||||
|
self.preference.register(
|
||||||
|
'keyboard_shortcuts',
|
||||||
|
'move_next',
|
||||||
|
gettext('Next tab'),
|
||||||
|
'keyboardshortcut',
|
||||||
|
{
|
||||||
|
'alt': True,
|
||||||
|
'shift': True,
|
||||||
|
'control': False,
|
||||||
|
'key': {
|
||||||
|
'key_code': 39,
|
||||||
|
'char': 'ArrowRight'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
category_label=gettext('Keyboard shortcuts'),
|
||||||
|
fields=shortcut_fields
|
||||||
|
)
|
||||||
|
|
||||||
|
# All about access keys
|
||||||
|
self.preference.register(
|
||||||
|
'keyboard_shortcuts', 'btn_open_file',
|
||||||
|
gettext('Accesskey (Open file)'), 'keyboardshortcut',
|
||||||
|
{
|
||||||
|
'key': {
|
||||||
|
'key_code': 79,
|
||||||
|
'char': 'o'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
category_label=gettext('Keyboard shortcuts'),
|
||||||
|
fields=accesskey_fields
|
||||||
|
)
|
||||||
|
|
||||||
|
self.preference.register(
|
||||||
|
'keyboard_shortcuts', 'btn_save_file',
|
||||||
|
gettext('Accesskey (Save file)'), 'keyboardshortcut',
|
||||||
|
{
|
||||||
|
'key': {
|
||||||
|
'key_code': 83,
|
||||||
|
'char': 's'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
category_label=gettext('Keyboard shortcuts'),
|
||||||
|
fields=accesskey_fields
|
||||||
|
)
|
||||||
|
|
||||||
|
self.preference.register(
|
||||||
|
'keyboard_shortcuts', 'btn_copy_row',
|
||||||
|
gettext('Accesskey (Copy rows)'), 'keyboardshortcut',
|
||||||
|
{
|
||||||
|
'key': {
|
||||||
|
'key_code': 67,
|
||||||
|
'char': 'c'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
category_label=gettext('Keyboard shortcuts'),
|
||||||
|
fields=accesskey_fields
|
||||||
|
)
|
||||||
|
|
||||||
|
self.preference.register(
|
||||||
|
'keyboard_shortcuts', 'btn_paste_row',
|
||||||
|
gettext('Accesskey (Paste rows)'), 'keyboardshortcut',
|
||||||
|
{
|
||||||
|
'key': {
|
||||||
|
'key_code': 80,
|
||||||
|
'char': 'p'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
category_label=gettext('Keyboard shortcuts'),
|
||||||
|
fields=accesskey_fields
|
||||||
|
)
|
||||||
|
|
||||||
|
self.preference.register(
|
||||||
|
'keyboard_shortcuts', 'btn_delete_row',
|
||||||
|
gettext('Accesskey (Delete rows)'), 'keyboardshortcut',
|
||||||
|
{
|
||||||
|
'key': {
|
||||||
|
'key_code': 68,
|
||||||
|
'char': 'd'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
category_label=gettext('Keyboard shortcuts'),
|
||||||
|
fields=accesskey_fields
|
||||||
|
)
|
||||||
|
|
||||||
|
self.preference.register(
|
||||||
|
'keyboard_shortcuts', 'btn_filter_dialog',
|
||||||
|
gettext('Accesskey (Filter dialog)'), 'keyboardshortcut',
|
||||||
|
{
|
||||||
|
'key': {
|
||||||
|
'key_code': 70,
|
||||||
|
'char': 'f'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
category_label=gettext('Keyboard shortcuts'),
|
||||||
|
fields=accesskey_fields
|
||||||
|
)
|
||||||
|
|
||||||
|
self.preference.register(
|
||||||
|
'keyboard_shortcuts', 'btn_filter_options',
|
||||||
|
gettext('Accesskey (Filter options)'), 'keyboardshortcut',
|
||||||
|
{
|
||||||
|
'key': {
|
||||||
|
'key_code': 73,
|
||||||
|
'char': 'i'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
category_label=gettext('Keyboard shortcuts'),
|
||||||
|
fields=accesskey_fields
|
||||||
|
)
|
||||||
|
|
||||||
|
self.preference.register(
|
||||||
|
'keyboard_shortcuts', 'btn_rows_limit',
|
||||||
|
gettext('Accesskey (Rows limit)'), 'keyboardshortcut',
|
||||||
|
{
|
||||||
|
'key': {
|
||||||
|
'key_code': 82,
|
||||||
|
'char': 'r'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
category_label=gettext('Keyboard shortcuts'),
|
||||||
|
fields=accesskey_fields
|
||||||
|
)
|
||||||
|
|
||||||
|
self.preference.register(
|
||||||
|
'keyboard_shortcuts', 'btn_execute_options',
|
||||||
|
gettext('Accesskey (Execute options)'), 'keyboardshortcut',
|
||||||
|
{
|
||||||
|
'key': {
|
||||||
|
'key_code': 88,
|
||||||
|
'char': 'x'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
category_label=gettext('Keyboard shortcuts'),
|
||||||
|
fields=accesskey_fields
|
||||||
|
)
|
||||||
|
|
||||||
|
self.preference.register(
|
||||||
|
'keyboard_shortcuts', 'btn_cancel_query',
|
||||||
|
gettext('Accesskey (Cancel query)'), 'keyboardshortcut',
|
||||||
|
{
|
||||||
|
'key': {
|
||||||
|
'key_code': 81,
|
||||||
|
'char': 'q'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
category_label=gettext('Keyboard shortcuts'),
|
||||||
|
fields=accesskey_fields
|
||||||
|
)
|
||||||
|
|
||||||
|
self.preference.register(
|
||||||
|
'keyboard_shortcuts', 'btn_clear_options',
|
||||||
|
gettext('Accesskey (Clear editor options)'), 'keyboardshortcut',
|
||||||
|
{
|
||||||
|
'key': {
|
||||||
|
'key_code': 76,
|
||||||
|
'char': 'l'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
category_label=gettext('Keyboard shortcuts'),
|
||||||
|
fields=accesskey_fields
|
||||||
|
)
|
||||||
|
|
||||||
|
self.preference.register(
|
||||||
|
'keyboard_shortcuts', 'btn_conn_status',
|
||||||
|
gettext('Accesskey (Connection status)'), 'keyboardshortcut',
|
||||||
|
{
|
||||||
|
'key': {
|
||||||
|
'key_code': 84,
|
||||||
|
'char': 't'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
category_label=gettext('Keyboard shortcuts'),
|
||||||
|
fields=accesskey_fields
|
||||||
|
)
|
||||||
|
|
||||||
|
self.preference.register(
|
||||||
|
'keyboard_shortcuts', 'btn_find_options',
|
||||||
|
gettext('Accesskey (Find options)'), 'keyboardshortcut',
|
||||||
|
{
|
||||||
|
'key': {
|
||||||
|
'key_code': 78,
|
||||||
|
'char': 'n'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
category_label=gettext('Keyboard shortcuts'),
|
||||||
|
fields=accesskey_fields
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_query_tool_keyboard_shortcuts():
|
||||||
|
|
||||||
|
"""
|
||||||
|
Fetch all the query tool shortcut preferences
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List of query tool shortcut preferences
|
||||||
|
"""
|
||||||
|
qt_perf = Preferences.module('sqleditor')
|
||||||
|
conn_status = qt_perf.preference('btn_conn_status').get()
|
||||||
|
clear_options = qt_perf.preference('btn_clear_options').get()
|
||||||
|
cancel_query = qt_perf.preference('btn_cancel_query').get()
|
||||||
|
execute_options = qt_perf.preference('btn_execute_options').get()
|
||||||
|
filter_options = qt_perf.preference('btn_filter_options').get()
|
||||||
|
rows_limit = qt_perf.preference('btn_rows_limit').get()
|
||||||
|
filter_dialog = qt_perf.preference('btn_filter_dialog').get()
|
||||||
|
delete_row = qt_perf.preference('btn_delete_row').get()
|
||||||
|
paste_row = qt_perf.preference('btn_paste_row').get()
|
||||||
|
copy_row = qt_perf.preference('btn_copy_row').get()
|
||||||
|
save_file = qt_perf.preference('btn_save_file').get()
|
||||||
|
open_file = qt_perf.preference('btn_open_file').get()
|
||||||
|
move_next = qt_perf.preference('move_next').get()
|
||||||
|
move_previous = qt_perf.preference('move_previous').get()
|
||||||
|
download_csv = qt_perf.preference('download_csv').get()
|
||||||
|
execute_query = qt_perf.preference('execute_query').get()
|
||||||
|
explain_query = qt_perf.preference('explain_query').get()
|
||||||
|
explain_analyze_query = qt_perf.preference('explain_analyze_query').get()
|
||||||
|
find_options = qt_perf.preference('btn_find_options').get()
|
||||||
|
|
||||||
|
return {
|
||||||
|
'keys': {
|
||||||
|
'conn_status': conn_status.get('key').get('char'),
|
||||||
|
'clear_options': clear_options.get('key').get('char'),
|
||||||
|
'cancel_query': cancel_query.get('key').get('char'),
|
||||||
|
'execute_options': execute_options.get('key').get('char'),
|
||||||
|
'filter_options': filter_options.get('key').get('char'),
|
||||||
|
'rows_limit': rows_limit.get('key').get('char'),
|
||||||
|
'filter_dialog': filter_dialog.get('key').get('char'),
|
||||||
|
'delete_row': delete_row.get('key').get('char'),
|
||||||
|
'paste_row': paste_row.get('key').get('char'),
|
||||||
|
'copy_row': copy_row.get('key').get('char'),
|
||||||
|
'save_file': save_file.get('key').get('char'),
|
||||||
|
'open_file': open_file.get('key').get('char'),
|
||||||
|
'move_next': move_next.get('key').get('char'),
|
||||||
|
'move_previous': move_previous.get('key').get('char'),
|
||||||
|
'download_csv': download_csv.get('key').get('char'),
|
||||||
|
'execute_query': execute_query.get('key').get('char'),
|
||||||
|
'explain_query': explain_query.get('key').get('char'),
|
||||||
|
'explain_analyze_query': explain_analyze_query.get('key').get(
|
||||||
|
'char'
|
||||||
|
),
|
||||||
|
'find_options': find_options.get('key').get('char')
|
||||||
|
},
|
||||||
|
'shortcuts': {
|
||||||
|
'conn_status': conn_status,
|
||||||
|
'clear_options': clear_options,
|
||||||
|
'cancel_query': cancel_query,
|
||||||
|
'execute_options': execute_options,
|
||||||
|
'filter_options': filter_options,
|
||||||
|
'rows_limit': rows_limit,
|
||||||
|
'filter_dialog': filter_dialog,
|
||||||
|
'delete_row': delete_row,
|
||||||
|
'paste_row': paste_row,
|
||||||
|
'copy_row': copy_row,
|
||||||
|
'save_file': save_file,
|
||||||
|
'open_file': open_file,
|
||||||
|
'move_next': move_next,
|
||||||
|
'move_previous': move_previous,
|
||||||
|
'download_csv': download_csv,
|
||||||
|
'execute_query': execute_query,
|
||||||
|
'explain_query': explain_query,
|
||||||
|
'explain_analyze_query': explain_analyze_query,
|
||||||
|
'find_options': find_options
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def get_text_representation_of_shortcut(shortcut):
|
||||||
|
"""
|
||||||
|
Coverts shortcut object to text representation
|
||||||
|
|
||||||
|
Args:
|
||||||
|
shortcut: Shortcut object
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Text representation of given shortcut
|
||||||
|
"""
|
||||||
|
text_representation = ''
|
||||||
|
is_plus_required = False
|
||||||
|
|
||||||
|
if not shortcut:
|
||||||
|
return text_representation
|
||||||
|
|
||||||
|
if shortcut['alt']:
|
||||||
|
text_representation = gettext('Alt')
|
||||||
|
is_plus_required = True
|
||||||
|
|
||||||
|
if shortcut['shift']:
|
||||||
|
if is_plus_required:
|
||||||
|
text_representation += '+'
|
||||||
|
text_representation += gettext('Shift')
|
||||||
|
is_plus_required = True
|
||||||
|
|
||||||
|
if shortcut['control']:
|
||||||
|
if is_plus_required:
|
||||||
|
text_representation += '+'
|
||||||
|
text_representation += gettext('Ctrl')
|
||||||
|
is_plus_required = True
|
||||||
|
|
||||||
|
if shortcut['key'] and shortcut['key']['char']:
|
||||||
|
if is_plus_required:
|
||||||
|
text_representation += '+'
|
||||||
|
text_representation += '{0}'.format(shortcut['key']['char'])
|
||||||
|
|
||||||
|
return text_representation
|
|
@ -11,6 +11,7 @@ from collections import defaultdict
|
||||||
from operator import attrgetter
|
from operator import attrgetter
|
||||||
|
|
||||||
from flask import Blueprint, current_app
|
from flask import Blueprint, current_app
|
||||||
|
from flask_babel import gettext
|
||||||
|
|
||||||
from .paths import get_storage_directory
|
from .paths import get_storage_directory
|
||||||
from .preferences import Preferences
|
from .preferences import Preferences
|
||||||
|
@ -280,3 +281,39 @@ def get_complete_file_path(file):
|
||||||
file = fs_short_path(file)
|
file = fs_short_path(file)
|
||||||
|
|
||||||
return file if os.path.isfile(file) else None
|
return file if os.path.isfile(file) else None
|
||||||
|
|
||||||
|
|
||||||
|
# Shortcut configuration for Accesskey
|
||||||
|
ACCESSKEY_FIELDS = [
|
||||||
|
{
|
||||||
|
'name': 'key',
|
||||||
|
'type': 'keyCode',
|
||||||
|
'label': gettext('Key')
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
# Shortcut configuration
|
||||||
|
SHORTCUT_FIELDS = [
|
||||||
|
{
|
||||||
|
'name': 'key',
|
||||||
|
'type': 'keyCode',
|
||||||
|
'label': gettext('Key')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'shift',
|
||||||
|
'type': 'checkbox',
|
||||||
|
'label': gettext('Shift')
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
'name': 'control',
|
||||||
|
'type': 'checkbox',
|
||||||
|
'label': gettext('Ctrl')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'alt',
|
||||||
|
'type': 'checkbox',
|
||||||
|
'label': gettext('Alt/Option')
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ describe('the keyboard shortcuts', () => {
|
||||||
PERIOD_KEY = 190,
|
PERIOD_KEY = 190,
|
||||||
FWD_SLASH_KEY = 191;
|
FWD_SLASH_KEY = 191;
|
||||||
|
|
||||||
let sqlEditorControllerSpy, event, queryToolActionsSpy;
|
let sqlEditorControllerSpy, event, queryToolActionsSpy, queryToolkeyboardShortcutsConfig;
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
event = {
|
event = {
|
||||||
shift: false,
|
shift: false,
|
||||||
|
@ -29,6 +29,57 @@ describe('the keyboard shortcuts', () => {
|
||||||
stopImmediatePropagation: jasmine.createSpy('stopImmediatePropagation'),
|
stopImmediatePropagation: jasmine.createSpy('stopImmediatePropagation'),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
queryToolkeyboardShortcutsConfig = {
|
||||||
|
execute: {
|
||||||
|
alt: false,
|
||||||
|
shift: false,
|
||||||
|
control: false,
|
||||||
|
key: {
|
||||||
|
key_code: F5_KEY
|
||||||
|
}
|
||||||
|
},
|
||||||
|
explain: {
|
||||||
|
alt: false,
|
||||||
|
shift: false,
|
||||||
|
control: false,
|
||||||
|
key: {
|
||||||
|
key_code: F7_KEY
|
||||||
|
}
|
||||||
|
},
|
||||||
|
explain_analyze: {
|
||||||
|
alt: false,
|
||||||
|
shift: true,
|
||||||
|
control: false,
|
||||||
|
key: {
|
||||||
|
key_code: F7_KEY
|
||||||
|
}
|
||||||
|
},
|
||||||
|
download_csv: {
|
||||||
|
alt: false,
|
||||||
|
shift: false,
|
||||||
|
control: false,
|
||||||
|
key: {
|
||||||
|
key_code: F8_KEY
|
||||||
|
}
|
||||||
|
},
|
||||||
|
move_next: {
|
||||||
|
alt: false,
|
||||||
|
shift: false,
|
||||||
|
control: false,
|
||||||
|
key: {
|
||||||
|
key_code: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
move_previous: {
|
||||||
|
alt: false,
|
||||||
|
shift: false,
|
||||||
|
control: false,
|
||||||
|
key: {
|
||||||
|
key_code: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
let gridView = {
|
let gridView = {
|
||||||
query_tool_obj: {
|
query_tool_obj: {
|
||||||
getSelection: jasmine.createSpy('getSelection'),
|
getSelection: jasmine.createSpy('getSelection'),
|
||||||
|
@ -42,6 +93,7 @@ describe('the keyboard shortcuts', () => {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
sqlEditorControllerSpy.gridView = gridView;
|
sqlEditorControllerSpy.gridView = gridView;
|
||||||
|
|
||||||
queryToolActionsSpy = jasmine.createSpyObj(queryToolActions, [
|
queryToolActionsSpy = jasmine.createSpyObj(queryToolActions, [
|
||||||
'explainAnalyze',
|
'explainAnalyze',
|
||||||
'explain',
|
'explain',
|
||||||
|
@ -57,7 +109,10 @@ describe('the keyboard shortcuts', () => {
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
event.which = F1_KEY;
|
event.which = F1_KEY;
|
||||||
keyboardShortcuts.processEventQueryTool(sqlEditorControllerSpy, queryToolActionsSpy, event);
|
keyboardShortcuts.processEventQueryTool(
|
||||||
|
sqlEditorControllerSpy, queryToolkeyboardShortcutsConfig,
|
||||||
|
queryToolActionsSpy, event
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow event to propagate', () => {
|
it('should allow event to propagate', () => {
|
||||||
|
@ -69,7 +124,13 @@ describe('the keyboard shortcuts', () => {
|
||||||
describe('when there is no query already running', () => {
|
describe('when there is no query already running', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
event.keyCode = F5_KEY;
|
event.keyCode = F5_KEY;
|
||||||
keyboardShortcuts.processEventQueryTool(sqlEditorControllerSpy, queryToolActionsSpy, event);
|
event.altKey = false;
|
||||||
|
event.shiftKey = false;
|
||||||
|
event.ctrlKey = false;
|
||||||
|
keyboardShortcuts.processEventQueryTool(
|
||||||
|
sqlEditorControllerSpy, queryToolkeyboardShortcutsConfig,
|
||||||
|
queryToolActionsSpy, event
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should execute the query', () => {
|
it('should execute the query', () => {
|
||||||
|
@ -84,9 +145,15 @@ describe('the keyboard shortcuts', () => {
|
||||||
describe('when the query is already running', () => {
|
describe('when the query is already running', () => {
|
||||||
it('does nothing', () => {
|
it('does nothing', () => {
|
||||||
event.keyCode = F5_KEY;
|
event.keyCode = F5_KEY;
|
||||||
|
event.altKey = false;
|
||||||
|
event.shiftKey = false;
|
||||||
|
event.ctrlKey = false;
|
||||||
sqlEditorControllerSpy.isQueryRunning.and.returnValue(true);
|
sqlEditorControllerSpy.isQueryRunning.and.returnValue(true);
|
||||||
|
|
||||||
keyboardShortcuts.processEventQueryTool(sqlEditorControllerSpy, queryToolActionsSpy, event);
|
keyboardShortcuts.processEventQueryTool(
|
||||||
|
sqlEditorControllerSpy, queryToolkeyboardShortcutsConfig,
|
||||||
|
queryToolActionsSpy, event
|
||||||
|
);
|
||||||
|
|
||||||
expect(queryToolActionsSpy.executeQuery).not.toHaveBeenCalled();
|
expect(queryToolActionsSpy.executeQuery).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
@ -97,7 +164,13 @@ describe('the keyboard shortcuts', () => {
|
||||||
describe('when there is not a query already running', () => {
|
describe('when there is not a query already running', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
event.which = F7_KEY;
|
event.which = F7_KEY;
|
||||||
keyboardShortcuts.processEventQueryTool(sqlEditorControllerSpy, queryToolActionsSpy, event);
|
event.altKey = false;
|
||||||
|
event.shiftKey = false;
|
||||||
|
event.ctrlKey = false;
|
||||||
|
keyboardShortcuts.processEventQueryTool(
|
||||||
|
sqlEditorControllerSpy, queryToolkeyboardShortcutsConfig,
|
||||||
|
queryToolActionsSpy, event
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should explain the query plan', () => {
|
it('should explain the query plan', () => {
|
||||||
|
@ -110,9 +183,15 @@ describe('the keyboard shortcuts', () => {
|
||||||
describe('when the query is already running', () => {
|
describe('when the query is already running', () => {
|
||||||
it('does nothing', () => {
|
it('does nothing', () => {
|
||||||
event.keyCode = F7_KEY;
|
event.keyCode = F7_KEY;
|
||||||
|
event.altKey = false;
|
||||||
|
event.shiftKey = false;
|
||||||
|
event.ctrlKey = false;
|
||||||
sqlEditorControllerSpy.isQueryRunning.and.returnValue(true);
|
sqlEditorControllerSpy.isQueryRunning.and.returnValue(true);
|
||||||
|
|
||||||
keyboardShortcuts.processEventQueryTool(sqlEditorControllerSpy, queryToolActionsSpy, event);
|
keyboardShortcuts.processEventQueryTool(
|
||||||
|
sqlEditorControllerSpy, queryToolkeyboardShortcutsConfig,
|
||||||
|
queryToolActionsSpy, event
|
||||||
|
);
|
||||||
|
|
||||||
expect(queryToolActionsSpy.explain).not.toHaveBeenCalled();
|
expect(queryToolActionsSpy.explain).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
@ -124,7 +203,12 @@ describe('the keyboard shortcuts', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
event.shiftKey = true;
|
event.shiftKey = true;
|
||||||
event.which = F7_KEY;
|
event.which = F7_KEY;
|
||||||
keyboardShortcuts.processEventQueryTool(sqlEditorControllerSpy, queryToolActionsSpy, event);
|
event.altKey = false;
|
||||||
|
event.ctrlKey = false;
|
||||||
|
keyboardShortcuts.processEventQueryTool(
|
||||||
|
sqlEditorControllerSpy, queryToolkeyboardShortcutsConfig,
|
||||||
|
queryToolActionsSpy, event
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should analyze explain the query plan', () => {
|
it('should analyze explain the query plan', () => {
|
||||||
|
@ -138,9 +222,15 @@ describe('the keyboard shortcuts', () => {
|
||||||
it('does nothing', () => {
|
it('does nothing', () => {
|
||||||
event.shiftKey = true;
|
event.shiftKey = true;
|
||||||
event.which = F7_KEY;
|
event.which = F7_KEY;
|
||||||
|
event.altKey = false;
|
||||||
|
event.ctrlKey = false;
|
||||||
|
|
||||||
sqlEditorControllerSpy.isQueryRunning.and.returnValue(true);
|
sqlEditorControllerSpy.isQueryRunning.and.returnValue(true);
|
||||||
|
|
||||||
keyboardShortcuts.processEventQueryTool(sqlEditorControllerSpy, queryToolActionsSpy, event);
|
keyboardShortcuts.processEventQueryTool(
|
||||||
|
sqlEditorControllerSpy, queryToolkeyboardShortcutsConfig,
|
||||||
|
queryToolActionsSpy, event
|
||||||
|
);
|
||||||
|
|
||||||
expect(queryToolActionsSpy.explainAnalyze).not.toHaveBeenCalled();
|
expect(queryToolActionsSpy.explainAnalyze).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
@ -151,7 +241,14 @@ describe('the keyboard shortcuts', () => {
|
||||||
describe('when there is not a query already running', () => {
|
describe('when there is not a query already running', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
event.which = F8_KEY;
|
event.which = F8_KEY;
|
||||||
keyboardShortcuts.processEventQueryTool(sqlEditorControllerSpy, queryToolActionsSpy, event);
|
event.altKey = false;
|
||||||
|
event.shiftKey = false;
|
||||||
|
event.ctrlKey = false;
|
||||||
|
|
||||||
|
keyboardShortcuts.processEventQueryTool(
|
||||||
|
sqlEditorControllerSpy, queryToolkeyboardShortcutsConfig,
|
||||||
|
queryToolActionsSpy, event
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should download the query results as a CSV', () => {
|
it('should download the query results as a CSV', () => {
|
||||||
|
@ -166,9 +263,16 @@ describe('the keyboard shortcuts', () => {
|
||||||
describe('when the query is already running', () => {
|
describe('when the query is already running', () => {
|
||||||
it('does nothing', () => {
|
it('does nothing', () => {
|
||||||
event.keyCode = F8_KEY;
|
event.keyCode = F8_KEY;
|
||||||
|
event.altKey = false;
|
||||||
|
event.shiftKey = false;
|
||||||
|
event.ctrlKey = false;
|
||||||
|
|
||||||
sqlEditorControllerSpy.isQueryRunning.and.returnValue(true);
|
sqlEditorControllerSpy.isQueryRunning.and.returnValue(true);
|
||||||
|
|
||||||
keyboardShortcuts.processEventQueryTool(sqlEditorControllerSpy, queryToolActionsSpy, event);
|
keyboardShortcuts.processEventQueryTool(
|
||||||
|
sqlEditorControllerSpy, queryToolkeyboardShortcutsConfig,
|
||||||
|
queryToolActionsSpy, event
|
||||||
|
);
|
||||||
|
|
||||||
expect(queryToolActionsSpy.download).not.toHaveBeenCalled();
|
expect(queryToolActionsSpy.download).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
@ -181,7 +285,10 @@ describe('the keyboard shortcuts', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
macKeysSetup();
|
macKeysSetup();
|
||||||
event.which = FWD_SLASH_KEY;
|
event.which = FWD_SLASH_KEY;
|
||||||
keyboardShortcuts.processEventQueryTool(sqlEditorControllerSpy, queryToolActionsSpy, event);
|
keyboardShortcuts.processEventQueryTool(
|
||||||
|
sqlEditorControllerSpy, queryToolkeyboardShortcutsConfig,
|
||||||
|
queryToolActionsSpy, event
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should comment the line', () => {
|
it('should comment the line', () => {
|
||||||
|
@ -195,7 +302,10 @@ describe('the keyboard shortcuts', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
windowsKeysSetup();
|
windowsKeysSetup();
|
||||||
event.which = FWD_SLASH_KEY;
|
event.which = FWD_SLASH_KEY;
|
||||||
keyboardShortcuts.processEventQueryTool(sqlEditorControllerSpy, queryToolActionsSpy, event);
|
keyboardShortcuts.processEventQueryTool(
|
||||||
|
sqlEditorControllerSpy, queryToolkeyboardShortcutsConfig,
|
||||||
|
queryToolActionsSpy, event
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should comment the line', () => {
|
it('should comment the line', () => {
|
||||||
|
@ -217,7 +327,10 @@ describe('the keyboard shortcuts', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does nothing', () => {
|
it('does nothing', () => {
|
||||||
keyboardShortcuts.processEventQueryTool(sqlEditorControllerSpy, queryToolActionsSpy, event);
|
keyboardShortcuts.processEventQueryTool(
|
||||||
|
sqlEditorControllerSpy, queryToolkeyboardShortcutsConfig,
|
||||||
|
queryToolActionsSpy, event
|
||||||
|
);
|
||||||
|
|
||||||
expect(queryToolActionsSpy.commentLineCode).not.toHaveBeenCalled();
|
expect(queryToolActionsSpy.commentLineCode).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
@ -230,7 +343,10 @@ describe('the keyboard shortcuts', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does nothing', () => {
|
it('does nothing', () => {
|
||||||
keyboardShortcuts.processEventQueryTool(sqlEditorControllerSpy, queryToolActionsSpy, event);
|
keyboardShortcuts.processEventQueryTool(
|
||||||
|
sqlEditorControllerSpy, queryToolkeyboardShortcutsConfig,
|
||||||
|
queryToolActionsSpy, event
|
||||||
|
);
|
||||||
|
|
||||||
expect(queryToolActionsSpy.commentLineCode).not.toHaveBeenCalled();
|
expect(queryToolActionsSpy.commentLineCode).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
@ -244,7 +360,10 @@ describe('the keyboard shortcuts', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
macKeysSetup();
|
macKeysSetup();
|
||||||
event.which = PERIOD_KEY;
|
event.which = PERIOD_KEY;
|
||||||
keyboardShortcuts.processEventQueryTool(sqlEditorControllerSpy, queryToolActionsSpy, event);
|
keyboardShortcuts.processEventQueryTool(
|
||||||
|
sqlEditorControllerSpy, queryToolkeyboardShortcutsConfig,
|
||||||
|
queryToolActionsSpy, event
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should uncomment the line', () => {
|
it('should uncomment the line', () => {
|
||||||
|
@ -257,7 +376,10 @@ describe('the keyboard shortcuts', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
windowsKeysSetup();
|
windowsKeysSetup();
|
||||||
event.which = PERIOD_KEY;
|
event.which = PERIOD_KEY;
|
||||||
keyboardShortcuts.processEventQueryTool(sqlEditorControllerSpy, queryToolActionsSpy, event);
|
keyboardShortcuts.processEventQueryTool(
|
||||||
|
sqlEditorControllerSpy, queryToolkeyboardShortcutsConfig,
|
||||||
|
queryToolActionsSpy, event
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should uncomment the line', () => {
|
it('should uncomment the line', () => {
|
||||||
|
@ -279,7 +401,10 @@ describe('the keyboard shortcuts', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does nothing', () => {
|
it('does nothing', () => {
|
||||||
keyboardShortcuts.processEventQueryTool(sqlEditorControllerSpy, queryToolActionsSpy, event);
|
keyboardShortcuts.processEventQueryTool(
|
||||||
|
sqlEditorControllerSpy, queryToolkeyboardShortcutsConfig,
|
||||||
|
queryToolActionsSpy, event
|
||||||
|
);
|
||||||
expect(queryToolActionsSpy.uncommentLineCode).not.toHaveBeenCalled();
|
expect(queryToolActionsSpy.uncommentLineCode).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -290,7 +415,10 @@ describe('the keyboard shortcuts', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does nothing', () => {
|
it('does nothing', () => {
|
||||||
keyboardShortcuts.processEventQueryTool(sqlEditorControllerSpy, queryToolActionsSpy, event);
|
keyboardShortcuts.processEventQueryTool(
|
||||||
|
sqlEditorControllerSpy, queryToolkeyboardShortcutsConfig,
|
||||||
|
queryToolActionsSpy, event
|
||||||
|
);
|
||||||
|
|
||||||
expect(queryToolActionsSpy.uncommentLineCode).not.toHaveBeenCalled();
|
expect(queryToolActionsSpy.uncommentLineCode).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
@ -305,7 +433,10 @@ describe('the keyboard shortcuts', () => {
|
||||||
macKeysSetup();
|
macKeysSetup();
|
||||||
event.which = FWD_SLASH_KEY;
|
event.which = FWD_SLASH_KEY;
|
||||||
event.shiftKey = true;
|
event.shiftKey = true;
|
||||||
keyboardShortcuts.processEventQueryTool(sqlEditorControllerSpy, queryToolActionsSpy, event);
|
keyboardShortcuts.processEventQueryTool(
|
||||||
|
sqlEditorControllerSpy, queryToolkeyboardShortcutsConfig,
|
||||||
|
queryToolActionsSpy, event
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should comment out the block selection', () => {
|
it('should comment out the block selection', () => {
|
||||||
|
@ -322,7 +453,10 @@ describe('the keyboard shortcuts', () => {
|
||||||
windowsKeysSetup();
|
windowsKeysSetup();
|
||||||
event.which = FWD_SLASH_KEY;
|
event.which = FWD_SLASH_KEY;
|
||||||
event.shiftKey = true;
|
event.shiftKey = true;
|
||||||
keyboardShortcuts.processEventQueryTool(sqlEditorControllerSpy, queryToolActionsSpy, event);
|
keyboardShortcuts.processEventQueryTool(
|
||||||
|
sqlEditorControllerSpy, queryToolkeyboardShortcutsConfig,
|
||||||
|
queryToolActionsSpy, event
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should comment out the block selection', () => {
|
it('should comment out the block selection', () => {
|
||||||
|
@ -342,7 +476,10 @@ describe('the keyboard shortcuts', () => {
|
||||||
macKeysSetup();
|
macKeysSetup();
|
||||||
event.which = FWD_SLASH_KEY;
|
event.which = FWD_SLASH_KEY;
|
||||||
event.shiftKey = true;
|
event.shiftKey = true;
|
||||||
keyboardShortcuts.processEventQueryTool(sqlEditorControllerSpy, queryToolActionsSpy, event);
|
keyboardShortcuts.processEventQueryTool(
|
||||||
|
sqlEditorControllerSpy, queryToolkeyboardShortcutsConfig,
|
||||||
|
queryToolActionsSpy, event
|
||||||
|
);
|
||||||
});
|
});
|
||||||
it('does nothing', () => {
|
it('does nothing', () => {
|
||||||
expect(queryToolActionsSpy.commentBlockCode).not.toHaveBeenCalled();
|
expect(queryToolActionsSpy.commentBlockCode).not.toHaveBeenCalled();
|
||||||
|
@ -353,7 +490,10 @@ describe('the keyboard shortcuts', () => {
|
||||||
windowsKeysSetup();
|
windowsKeysSetup();
|
||||||
event.which = FWD_SLASH_KEY;
|
event.which = FWD_SLASH_KEY;
|
||||||
event.shiftKey = true;
|
event.shiftKey = true;
|
||||||
keyboardShortcuts.processEventQueryTool(sqlEditorControllerSpy, queryToolActionsSpy, event);
|
keyboardShortcuts.processEventQueryTool(
|
||||||
|
sqlEditorControllerSpy, queryToolkeyboardShortcutsConfig,
|
||||||
|
queryToolActionsSpy, event
|
||||||
|
);
|
||||||
});
|
});
|
||||||
it('does nothing', () => {
|
it('does nothing', () => {
|
||||||
expect(queryToolActionsSpy.commentBlockCode).not.toHaveBeenCalled();
|
expect(queryToolActionsSpy.commentBlockCode).not.toHaveBeenCalled();
|
||||||
|
|
Loading…
Reference in New Issue