Introduced an ‘Editor’ preferences category and migrated all editor related settings into it. #8861

This commit is contained in:
Pravesh Sharma
2025-07-28 14:09:16 +05:30
committed by GitHub
parent e73d8f4532
commit 62eb330423
25 changed files with 599 additions and 438 deletions
+107
View File
@@ -0,0 +1,107 @@
##########################################################################
#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2025, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#
##########################################################################
"""Migrate the user saved preferences from the 'sqleditor' module to
the 'editor' module.
Revision ID: e6ed5dac37c2
Revises: e24b1c4def17
Create Date: 2025-07-15 12:27:48.780562
"""
from alembic import op
from sqlalchemy.orm.session import Session
from pgadmin.model import Preferences, ModulePreference, PreferenceCategory,\
UserPreference
from pgadmin.browser import register_editor_preferences
# revision identifiers, used by Alembic.
revision = 'e6ed5dac37c2'
down_revision = 'e24b1c4def17'
branch_labels = None
depends_on = None
class Migration:
"""
This is a placeholder class for registering editor preferences
"""
def __init__(self, value=None):
self.editor_preference = value
def upgrade():
migration_obj = Migration()
register_editor_preferences(migration_obj, migration_gettext=lambda x: x)
session = Session(bind=op.get_bind())
pref_categories = ['keyboard_shortcuts', 'editor', 'Editor']
new_categories = ['keyboard_shortcuts', 'sql_formatting', 'options']
prefs = ['find', 'replace', 'goto_line_col',
'comment', 'format_sql', 'plain_editor_mode',
'code_folding', 'wrap_code', 'insert_pair_brackets',
'highlight_selection_matches', 'brace_matching', 'sql_font_size',
'sql_font_ligatures', 'sql_font_family', 'indent_new_line',
'keyword_case', 'identifier_case', 'function_case',
'data_type_case', 'spaces_around_operators', 'tab_size',
'use_spaces', 'expression_width', 'logical_operator_new_line',
'lines_between_queries', 'new_line_before_semicolon']
category_ids = []
new_ids = []
pref_map = {}
category_data = session.query(ModulePreference, PreferenceCategory,).join(
PreferenceCategory).filter(
ModulePreference.name == 'sqleditor',
PreferenceCategory.name.in_(pref_categories)).all()
for module_data, pref_cat in category_data:
category_ids.append(pref_cat.id)
new_data = session.query(ModulePreference, PreferenceCategory).join(
PreferenceCategory).filter(
ModulePreference.name == 'editor', PreferenceCategory.name.in_(
new_categories)).all()
for module_data, pref_cat in new_data:
new_ids.append(pref_cat.id)
prefs_data = session.query(Preferences).filter(Preferences.cid.in_(
category_ids), Preferences.name.in_(prefs)).all()
new_prefs_data = session.query(Preferences).filter(Preferences.cid.in_(
new_ids), Preferences.name.in_(prefs)).all()
for pref in prefs_data:
for new_pref in new_prefs_data:
if pref.name == new_pref.name:
pref_map[pref.id] = new_pref.id
for key, val in pref_map.items():
record_to_update = session.query(UserPreference).filter_by(
pid=key).first()
if record_to_update:
record_to_update.pid = val
# Delete the old preferences and categories
session.query(Preferences).filter(Preferences.name.in_(prefs),
Preferences.cid.in_(category_ids)
).delete(synchronize_session=False)
session.query(PreferenceCategory).filter(
PreferenceCategory.name.in_(['editor', 'Editor'])).delete(
synchronize_session=False)
session.commit()
def downgrade():
# pgAdmin only upgrades, downgrade not implemented.
pass
+3
View File
@@ -52,6 +52,8 @@ from pgadmin.utils.csrf import pgCSRFProtect
from pgadmin.utils.preferences import Preferences
from pgadmin.browser.register_browser_preferences import \
register_browser_preferences
from pgadmin.browser.register_editor_preferences import \
register_editor_preferences
from pgadmin.utils.master_password import validate_master_password, \
set_masterpass_check_text, cleanup_master_password, get_crypt_key, \
set_crypt_key, process_masterpass_disabled, \
@@ -87,6 +89,7 @@ class BrowserModule(PgAdminModule):
def register_preferences(self):
register_browser_preferences(self)
register_editor_preferences(self)
def get_exposed_url_endpoints(self):
"""
@@ -0,0 +1,357 @@
##########################################################################
#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2025, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#
##########################################################################
from flask_babel import gettext
from pgadmin.utils.preferences import Preferences
from pgadmin.utils.constants import PREF_LABEL_OPTIONS,\
PREF_LABEL_KEYBOARD_SHORTCUTS, PREF_LABEL_SQL_FORMATTING
from pgadmin.utils import SHORTCUT_FIELDS as shortcut_fields
UPPER_CASE_STR = gettext('Upper case')
LOWER_CASE_STR = gettext('Lower case')
PRESERVE_STR = gettext('Preserve')
def register_editor_preferences(self, migration_gettext=None):
"""
Registers the editor preferences
"""
# migration_getttext is used once in case of migration
# In that case gettext will be used from migration_gettext
# instead of flask_babel gettext.
from flask_babel import gettext
if migration_gettext is not None:
gettext = migration_gettext
self.editor_preference = Preferences(
'editor', gettext('Editor')
)
self.editor_preference.register(
'keyboard_shortcuts',
'find',
gettext('Find'),
'keyboardshortcut',
{
'alt': False,
'shift': False,
'control': True,
'ctrl_is_meta': True,
'key': {
'key_code': 70,
'char': 'f'
}
},
category_label=PREF_LABEL_KEYBOARD_SHORTCUTS,
fields=shortcut_fields
)
self.editor_preference.register(
'keyboard_shortcuts',
'replace',
gettext('Replace'),
'keyboardshortcut',
{
'alt': True,
'shift': False,
'control': True,
'ctrl_is_meta': True,
'key': {
'key_code': 70,
'char': 'f'
}
},
category_label=PREF_LABEL_KEYBOARD_SHORTCUTS,
fields=shortcut_fields
)
self.editor_preference.register(
'keyboard_shortcuts',
'goto_line_col',
gettext('Go to line/column'),
'keyboardshortcut',
{
'alt': False,
'shift': False,
'control': True,
'ctrl_is_meta': True,
'key': {
'key_code': 76,
'char': 'l'
}
},
category_label=PREF_LABEL_KEYBOARD_SHORTCUTS,
fields=shortcut_fields
)
self.editor_preference.register(
'keyboard_shortcuts',
'comment',
gettext('Toggle comment'),
'keyboardshortcut',
{
'alt': False,
'shift': False,
'control': True,
'ctrl_is_meta': True,
'key': {
'key_code': 191,
'char': '/'
}
},
category_label=PREF_LABEL_KEYBOARD_SHORTCUTS,
fields=shortcut_fields
)
self.editor_preference.register(
'keyboard_shortcuts',
'format_sql',
gettext('Format SQL'),
'keyboardshortcut',
{
'alt': False,
'shift': False,
'control': True,
'ctrl_is_meta': True,
'key': {
'key_code': 75,
'char': 'k'
}
},
category_label=PREF_LABEL_KEYBOARD_SHORTCUTS,
fields=shortcut_fields
)
self.editor_preference.register(
'options', 'plain_editor_mode',
gettext("Plain text mode?"), 'boolean', False,
category_label=PREF_LABEL_OPTIONS,
help_str=gettext(
'When set to True, keywords won\'t be highlighted and code '
'folding will be disabled. Plain text mode will improve editor '
'performance with large files.'
)
)
self.editor_preference.register(
'options', 'code_folding',
gettext("Code folding?"), 'boolean', True,
category_label=PREF_LABEL_OPTIONS,
help_str=gettext(
'Enable or disable code folding. In plain text mode, this will '
'have no effect as code folding is always disabled in that mode. '
'Disabling will improve editor performance with large files.'
)
)
self.editor_preference.register(
'options', 'wrap_code',
gettext("Line wrapping?"), 'boolean', False,
category_label=PREF_LABEL_OPTIONS,
help_str=gettext(
'Specifies whether or not to wrap SQL code in the editor.'
)
)
self.editor_preference.register(
'options', 'insert_pair_brackets',
gettext("Insert bracket pairs?"), 'boolean', True,
category_label=PREF_LABEL_OPTIONS,
help_str=gettext(
'Specifies whether or not to insert paired brackets in the '
'editor.'
)
)
self.editor_preference.register(
'options', 'highlight_selection_matches',
gettext("Highlight selection matches?"), 'boolean', True,
category_label=PREF_LABEL_OPTIONS,
help_str=gettext(
'Specifies whether or not to highlight matched selected text '
'in the editor.'
)
)
self.editor_preference.register(
'options', 'brace_matching',
gettext("Brace matching?"), 'boolean', True,
category_label=PREF_LABEL_OPTIONS,
help_str=gettext(
'Specifies whether or not to highlight matched braces '
'in the editor.'
)
)
self.editor_preference.register(
'options', 'sql_font_size',
gettext("Font size"), 'numeric', '1',
min_val=0.1,
max_val=10,
category_label=PREF_LABEL_OPTIONS,
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.editor_preference.register(
'options', 'sql_font_ligatures',
gettext("Font ligatures?"), 'boolean',
False, category_label=PREF_LABEL_OPTIONS,
help_str=gettext(
'If set to true, ligatures will be enabled in SQL text boxes '
'and editors provided the configured font family supports them.'
)
)
self.editor_preference.register(
'options', 'sql_font_family',
gettext("Font family"), 'text', 'Source Code Pro',
category_label=PREF_LABEL_OPTIONS,
help_str=gettext(
'Specify the font family to be used for all SQL editors. '
'The specified font should already be installed on your system. '
'If the font is not found, the editor will fall back to the '
'default font, Source Code Pro.'
)
)
self.editor_preference.register(
'options', 'indent_new_line',
gettext("Auto-indent new line?"), 'boolean', True,
category_label=PREF_LABEL_OPTIONS,
help_str=gettext(
'Specifies whether the newly added line using enter key should '
'be auto-indented or not'
)
)
self.editor_preference.register(
'sql_formatting', 'keyword_case',
gettext("Keyword case"), 'radioModern', 'upper',
options=[{'label': UPPER_CASE_STR, 'value': 'upper'},
{'label': LOWER_CASE_STR, 'value': 'lower'},
{'label': PRESERVE_STR, 'value': 'preserve'}],
category_label=PREF_LABEL_SQL_FORMATTING,
help_str=gettext(
'Convert keywords to upper, lower, or preserve casing.'
)
)
self.editor_preference.register(
'sql_formatting', 'identifier_case',
gettext("Identifier case"), 'radioModern', 'upper',
options=[{'label': UPPER_CASE_STR, 'value': 'upper'},
{'label': LOWER_CASE_STR, 'value': 'lower'},
{'label': PRESERVE_STR, 'value': 'preserve'}],
category_label=PREF_LABEL_SQL_FORMATTING,
help_str=gettext(
'Convert identifiers to upper, lower, or preserve casing.'
)
)
self.editor_preference.register(
'sql_formatting', 'function_case',
gettext("Function case"), 'radioModern', 'upper',
options=[{'label': UPPER_CASE_STR, 'value': 'upper'},
{'label': LOWER_CASE_STR, 'value': 'lower'},
{'label': PRESERVE_STR, 'value': 'preserve'}],
category_label=PREF_LABEL_SQL_FORMATTING,
help_str=gettext(
'Convert function names to upper, lower, or preserve casing.'
)
)
self.editor_preference.register(
'sql_formatting', 'data_type_case',
gettext("Data type case"), 'radioModern', 'upper',
options=[{'label': UPPER_CASE_STR, 'value': 'upper'},
{'label': LOWER_CASE_STR, 'value': 'lower'},
{'label': PRESERVE_STR, 'value': 'preserve'}],
category_label=PREF_LABEL_SQL_FORMATTING,
help_str=gettext(
'Convert data types to upper, lower, or preserve casing.'
)
)
self.editor_preference.register(
'sql_formatting', 'spaces_around_operators',
gettext("Spaces around operators?"), 'boolean', True,
category_label=PREF_LABEL_SQL_FORMATTING,
help_str=gettext('If set to True, spaces are used around all '
'operators.')
)
self.editor_preference.register(
'sql_formatting', 'tab_size',
gettext("Tab size"), 'integer', 4,
min_val=2,
max_val=8,
category_label=PREF_LABEL_SQL_FORMATTING,
help_str=gettext(
'The number of spaces per tab. Minimum 2, maximum 8.'
)
)
self.editor_preference.register(
'sql_formatting', 'use_spaces',
gettext("Use spaces?"), 'boolean', False,
category_label=PREF_LABEL_SQL_FORMATTING,
help_str=gettext(
'Specifies whether or not to insert spaces instead of tabs '
'when the tab key or auto-indent are used.'
)
)
self.editor_preference.register(
'sql_formatting', 'expression_width',
gettext("Expression Width"), 'integer', 50,
category_label=PREF_LABEL_SQL_FORMATTING,
help_str=gettext(
'maximum number of characters in parenthesized expressions to be '
'kept on single line.'
)
)
self.editor_preference.register(
'sql_formatting', 'logical_operator_new_line',
gettext("Logical operator new line"), 'radioModern', 'before',
options=[{'label': gettext('Before'), 'value': 'before'},
{'label': gettext('After'), 'value': 'after'}],
category_label=PREF_LABEL_SQL_FORMATTING,
help_str=gettext(
'Decides newline placement before or after logical operators '
'(AND, OR, XOR).'
)
)
self.editor_preference.register(
'sql_formatting', 'lines_between_queries',
gettext("Lines between queries"), 'integer', 1,
min_val=0,
max_val=5,
category_label=PREF_LABEL_SQL_FORMATTING,
help_str=gettext(
'Decides how many empty lines to leave between SQL statements. '
'If zero it puts no new line.'
)
)
self.editor_preference.register(
'sql_formatting', 'new_line_before_semicolon',
gettext("New line before semicolon?"), 'boolean', False,
category_label=PREF_LABEL_SQL_FORMATTING,
help_str=gettext(
'Whether to place query separator (;) on a separate line.'
)
)
+1 -1
View File
@@ -33,7 +33,7 @@ import config
#
##########################################################################
SCHEMA_VERSION = 46
SCHEMA_VERSION = 47
##########################################################################
#
@@ -285,14 +285,15 @@ export default function Editor({
useEffect(() => {
if (!checkIsMounted()) return;
let pref = preferencesStore.getPreferencesForModule('sqleditor');
let editorPref = preferencesStore.getPreferencesForModule('editor');
let newConfigExtn = [];
const fontSize = calcFontSize(pref.sql_font_size);
const fontSize = calcFontSize(editorPref.sql_font_size);
newConfigExtn.push(EditorView.theme({
'& .cm-scroller .cm-content': {
fontSize: fontSize,
fontVariantLigatures: pref.sql_font_ligatures ? 'normal' : 'none',
fontFamily: `${pref.sql_font_family}, ${theme.typography.fontFamilySourceCode}`,
fontVariantLigatures: editorPref.sql_font_ligatures ? 'normal' : 'none',
fontFamily: `${editorPref.sql_font_family}, ${theme.typography.fontFamilySourceCode}`,
},
'.cm-gutters': {
fontSize: fontSize,
@@ -336,11 +337,11 @@ export default function Editor({
}
newConfigExtn.push(
EditorState.tabSize.of(pref.tab_size),
EditorState.tabSize.of(editorPref.tab_size),
);
if (pref.use_spaces) {
if (editorPref.use_spaces) {
newConfigExtn.push(
indentUnit.of(' '.repeat(pref.tab_size)),
indentUnit.of(' '.repeat(editorPref.tab_size)),
);
} else {
newConfigExtn.push(
@@ -348,34 +349,34 @@ export default function Editor({
);
}
if(pref.indent_new_line) {
if(editorPref.indent_new_line) {
newConfigExtn.push(indentNewLine.of(true));
} else {
newConfigExtn.push(indentNewLine.of(false));
}
if (pref.wrap_code) {
if (editorPref.wrap_code) {
newConfigExtn.push(
EditorView.lineWrapping
);
}
if (pref.insert_pair_brackets) {
if (editorPref.insert_pair_brackets) {
newConfigExtn.push(closeBrackets());
}
if (pref.highlight_selection_matches){
if (editorPref.highlight_selection_matches){
newConfigExtn.push(highlightSelectionMatches());
}
if (pref.brace_matching) {
if (editorPref.brace_matching) {
newConfigExtn.push(bracketMatching());
}
if (pref.underline_query_cursor){
newConfigExtn.push(currentQueryHighlighterExtn());
}
if(!pref.plain_editor_mode) {
if(!editorPref.plain_editor_mode) {
// lang override
if(language == 'json') {
newConfigExtn.push(json());
@@ -384,7 +385,7 @@ export default function Editor({
}
}
if(pref.code_folding && finalOptions.foldGutter) {
if(editorPref.code_folding && finalOptions.foldGutter) {
newConfigExtn.push(foldGutter({
markerDOM: (open)=>{
let icon = document.createElement('span');
@@ -399,7 +400,7 @@ export default function Editor({
}
// add fold service conditionally
if(!pref.plain_editor_mode && pref.code_folding && language == 'pgsql') {
if(!editorPref.plain_editor_mode && editorPref.code_folding && language == 'pgsql') {
newConfigExtn.push(plpgsqlFoldService);
}
@@ -69,6 +69,7 @@ export default function CodeMirror({className, currEditor, showCopyBtn=false, cu
const [showGoto, setShowGoto] = useState(false);
const [showCopy, setShowCopy] = useState(false);
const preferences = usePreferences().getPreferencesForModule('sqleditor');
const editorPrefs = usePreferences().getPreferencesForModule('editor');
const formatSQL = (view)=>{
let selection = true, sql = view.getSelection();
@@ -78,17 +79,17 @@ export default function CodeMirror({className, currEditor, showCopyBtn=false, cu
*/
let formatPrefs = {
language: 'postgresql',
keywordCase: preferences.keyword_case === 'capitalize' ? 'preserve' : preferences.keyword_case,
identifierCase: preferences.identifier_case === 'capitalize' ? 'preserve' : preferences.identifier_case,
dataTypeCase: preferences.data_type_case,
functionCase: preferences.function_case,
logicalOperatorNewline: preferences.logical_operator_new_line,
expressionWidth: preferences.expression_width,
linesBetweenQueries: preferences.lines_between_queries,
tabWidth: preferences.tab_size,
useTabs: !preferences.use_spaces,
denseOperators: !preferences.spaces_around_operators,
newlineBeforeSemicolon: preferences.new_line_before_semicolon
keywordCase: editorPrefs.keyword_case === 'capitalize' ? 'preserve' : editorPrefs.keyword_case,
identifierCase: editorPrefs.identifier_case === 'capitalize' ? 'preserve' : editorPrefs.identifier_case,
dataTypeCase: editorPrefs.data_type_case,
functionCase: editorPrefs.function_case,
logicalOperatorNewline: editorPrefs.logical_operator_new_line,
expressionWidth: editorPrefs.expression_width,
linesBetweenQueries: editorPrefs.lines_between_queries,
tabWidth: editorPrefs.tab_size,
useTabs: !editorPrefs.use_spaces,
denseOperators: !editorPrefs.spaces_around_operators,
newlineBeforeSemicolon: editorPrefs.new_line_before_semicolon
};
if(sql == '') {
sql = view.getValue();
@@ -103,31 +104,31 @@ export default function CodeMirror({className, currEditor, showCopyBtn=false, cu
};
const finalCustomKeyMap = useMemo(()=>[{
key: toCodeMirrorKey(preferences.find), run: () => {
key: toCodeMirrorKey(editorPrefs.find), run: () => {
setShowFind(prevVal => [true, false, !prevVal[2]]);
},
preventDefault: true,
stopPropagation: true,
}, {
key: toCodeMirrorKey(preferences.replace), run: () => {
key: toCodeMirrorKey(editorPrefs.replace), run: () => {
setShowFind(prevVal => [true, true, !prevVal[2]]);
},
preventDefault: true,
stopPropagation: true,
}, {
key: toCodeMirrorKey(preferences.goto_line_col), run: () => {
key: toCodeMirrorKey(editorPrefs.goto_line_col), run: () => {
setShowGoto(true);
},
preventDefault: true,
stopPropagation: true,
}, {
key: toCodeMirrorKey(preferences.comment), run: () => {
key: toCodeMirrorKey(editorPrefs.comment), run: () => {
editor.current?.execCommand('toggleComment');
},
preventDefault: true,
stopPropagation: true,
},{
key: toCodeMirrorKey(preferences.format_sql), run: formatSQL,
key: toCodeMirrorKey(editorPrefs.format_sql), run: formatSQL,
preventDefault: true,
stopPropagation: true,
},{
@@ -123,6 +123,7 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
sqleditor: {...preferencesStore.getPreferencesForModule('sqleditor'), ...FIXED_PREF},
graphs: preferencesStore.getPreferencesForModule('graphs'),
misc: preferencesStore.getPreferencesForModule('misc'),
editor: preferencesStore.getPreferencesForModule('editor'),
},
is_new_tab: window.location == window.parent?.location,
is_visible: true,
@@ -467,6 +468,7 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
sqleditor: {...state.getPreferencesForModule('sqleditor'), ...FIXED_PREF},
graphs: state.getPreferencesForModule('graphs'),
misc: state.getPreferencesForModule('misc'),
editor: state.getPreferencesForModule('editor'),
}});
}
), []);
@@ -84,6 +84,7 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros, onAddT
const filterMenuRef = React.useRef(null);
const queryToolPref = queryToolCtx.preferences.sqleditor;
const editorPref = queryToolCtx.preferences.editor;
const setDisableButton = useCallback((name, disable=true)=>{
setButtonsDisabled((prev)=>({...prev, [name]: disable}));
}, []);
@@ -595,25 +596,25 @@ export function MainToolBar({containerRef, onFilterClick, onManageMacros, onAddT
onClose={onMenuClose}
label={gettext('Edit Menu')}
>
<PgMenuItem shortcut={queryToolPref.find}
<PgMenuItem shortcut={editorPref.find}
onClick={()=>{eventBus.fireEvent(QUERY_TOOL_EVENTS.EDITOR_FIND_REPLACE, false);}}>{gettext('Find')}</PgMenuItem>
<PgMenuItem shortcut={queryToolPref.replace}
<PgMenuItem shortcut={editorPref.replace}
onClick={()=>{eventBus.fireEvent(QUERY_TOOL_EVENTS.EDITOR_FIND_REPLACE, true);}}>{gettext('Replace')}</PgMenuItem>
<PgMenuItem shortcut={queryToolPref.goto_line_col}
<PgMenuItem shortcut={editorPref.goto_line_col}
onClick={()=>{executeCmd('gotoLineCol');}}>{gettext('Go to Line/Column')}</PgMenuItem>
<PgMenuDivider />
<PgMenuItem shortcut={queryToolPref.indent}
onClick={()=>{executeCmd('indentMore');}}>{gettext('Indent Selection')}</PgMenuItem>
<PgMenuItem shortcut={queryToolPref.unindent}
onClick={()=>{executeCmd('indentLess');}}>{gettext('Unindent Selection')}</PgMenuItem>
<PgMenuItem shortcut={queryToolPref.comment}
<PgMenuItem shortcut={editorPref.comment}
onClick={()=>{executeCmd('toggleComment');}}>{gettext('Toggle Comment')}</PgMenuItem>
<PgMenuItem shortcut={queryToolPref.toggle_case}
onClick={toggleCase}>{gettext('Toggle Case Of Selected Text')}</PgMenuItem>
<PgMenuItem shortcut={queryToolPref.clear_query}
onClick={clearQuery}>{gettext('Clear Query')}</PgMenuItem>
<PgMenuDivider />
<PgMenuItem shortcut={queryToolPref.format_sql} onClick={()=>{executeCmd('formatSql');}}>{gettext('Format SQL')}</PgMenuItem>
<PgMenuItem shortcut={editorPref.format_sql} onClick={()=>{executeCmd('formatSql');}}>{gettext('Format SQL')}</PgMenuItem>
</PgMenu>
<PgMenu
anchorRef={filterMenuRef}
@@ -309,8 +309,8 @@ export default function Query({onTextSelect, setQtStatePartial}) {
};
const unregisterEditorExecCmd = eventBus.registerListener(QUERY_TOOL_EVENTS.EDITOR_EXEC_CMD, (cmd='')=>{
let key = {}, gotolinecol = queryToolCtx.preferences.sqleditor.goto_line_col,
formatSql = queryToolCtx.preferences.sqleditor.format_sql;
let key = {}, gotolinecol = queryToolCtx.preferences.editor.goto_line_col,
formatSql = queryToolCtx.preferences.editor.format_sql;
switch(cmd) {
case 'gotoLineCol':
key = createKeyObjectFromShortcut(gotolinecol);
@@ -326,8 +326,8 @@ export default function Query({onTextSelect, setQtStatePartial}) {
});
const unregisterFindReplace = eventBus.registerListener(QUERY_TOOL_EVENTS.EDITOR_FIND_REPLACE, (replace=false)=>{
let findShortcut = queryToolCtx.preferences.sqleditor.find;
let replaceShortcut = queryToolCtx.preferences.sqleditor.replace;
let findShortcut = queryToolCtx.preferences.editor.find;
let replaceShortcut = queryToolCtx.preferences.editor.replace;
let key ={};
editor.current?.focus();
if (!replace) {
@@ -11,15 +11,11 @@
from flask_babel import gettext
from pgadmin.utils.constants import PREF_LABEL_DISPLAY,\
PREF_LABEL_KEYBOARD_SHORTCUTS, PREF_LABEL_EXPLAIN, PREF_LABEL_OPTIONS,\
PREF_LABEL_EDITOR, PREF_LABEL_CSV_TXT, PREF_LABEL_RESULTS_GRID,\
PREF_LABEL_SQL_FORMATTING, PREF_LABEL_GRAPH_VISUALISER
PREF_LABEL_CSV_TXT, PREF_LABEL_RESULTS_GRID,\
PREF_LABEL_GRAPH_VISUALISER
from pgadmin.utils import SHORTCUT_FIELDS as shortcut_fields
from config import DATA_RESULT_ROWS_PER_PAGE
UPPER_CASE_STR = gettext('Upper case')
LOWER_CASE_STR = gettext('Lower case')
PRESERVE_STR = gettext('Preserve')
def register_query_tool_preferences(self):
self.explain_verbose = self.preference.register(
@@ -188,67 +184,6 @@ def register_query_tool_preferences(self):
)
)
self.preference.register(
'Editor', 'plain_editor_mode',
gettext("Plain text mode?"), 'boolean', False,
category_label=PREF_LABEL_EDITOR,
help_str=gettext(
'When set to True, keywords won\'t be highlighted and code '
'folding will be disabled. Plain text mode will improve editor '
'performance with large files.'
)
)
self.preference.register(
'Editor', 'code_folding',
gettext("Code folding?"), 'boolean', True,
category_label=PREF_LABEL_EDITOR,
help_str=gettext(
'Enable or disable code folding. In plain text mode, this will '
'have no effect as code folding is always disabled in that mode. '
'Disabling will improve editor performance with large files.'
)
)
self.wrap_code = self.preference.register(
'Editor', 'wrap_code',
gettext("Line wrapping?"), 'boolean', False,
category_label=PREF_LABEL_OPTIONS,
help_str=gettext(
'Specifies whether or not to wrap SQL code in the editor.'
)
)
self.insert_pair_brackets = self.preference.register(
'Editor', 'insert_pair_brackets',
gettext("Insert bracket pairs?"), 'boolean', True,
category_label=PREF_LABEL_OPTIONS,
help_str=gettext(
'Specifies whether or not to insert paired brackets in the '
'editor.'
)
)
self.highlight_selection_matches = self.preference.register(
'Editor', 'highlight_selection_matches',
gettext("Highlight selection matches?"), 'boolean', True,
category_label=PREF_LABEL_OPTIONS,
help_str=gettext(
'Specifies whether or not to highlight matched selected text '
'in the editor.'
)
)
self.brace_matching = self.preference.register(
'Editor', 'brace_matching',
gettext("Brace matching?"), 'boolean', True,
category_label=PREF_LABEL_OPTIONS,
help_str=gettext(
'Specifies whether or not to highlight matched braces '
'in the editor.'
)
)
self.csv_quoting = self.preference.register(
'CSV_output', 'csv_quoting',
gettext("CSV quoting"), 'options', 'strings',
@@ -394,43 +329,6 @@ def register_query_tool_preferences(self):
' data output cell.')
)
self.sql_font_size = self.preference.register(
'Editor', 'sql_font_size',
gettext("Font size"), 'numeric', '1',
min_val=0.1,
max_val=10,
category_label=PREF_LABEL_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.sql_font_ligatures = self.preference.register(
'Editor', 'sql_font_ligatures',
gettext("Font ligatures?"), 'boolean',
False, category_label=PREF_LABEL_DISPLAY,
help_str=gettext(
'If set to true, ligatures will be enabled in SQL text boxes '
'and editors provided the configured font family supports them.'
)
)
self.sql_font_family = self.preference.register(
'Editor', 'sql_font_family',
gettext("Font family"), 'text', 'Source Code Pro',
category_label=PREF_LABEL_DISPLAY,
help_str=gettext(
'Specify the font family to be used for all SQL editors. '
'The specified font should already be installed on your system. '
'If the font is not found, the editor will fall back to the '
'default font, Source Code Pro.'
)
)
self.display_connection_status = self.preference.register(
'display', 'connection_status',
gettext("Connection status"), 'boolean', True,
@@ -884,101 +782,6 @@ def register_query_tool_preferences(self):
fields=shortcut_fields
)
self.preference.register(
'keyboard_shortcuts',
'find',
gettext('Find'),
'keyboardshortcut',
{
'alt': False,
'shift': False,
'control': True,
'ctrl_is_meta': True,
'key': {
'key_code': 70,
'char': 'f'
}
},
category_label=PREF_LABEL_KEYBOARD_SHORTCUTS,
fields=shortcut_fields
)
self.preference.register(
'keyboard_shortcuts',
'replace',
gettext('Replace'),
'keyboardshortcut',
{
'alt': True,
'shift': False,
'control': True,
'ctrl_is_meta': True,
'key': {
'key_code': 70,
'char': 'f'
}
},
category_label=PREF_LABEL_KEYBOARD_SHORTCUTS,
fields=shortcut_fields
)
self.preference.register(
'keyboard_shortcuts',
'goto_line_col',
gettext('Go to line/column'),
'keyboardshortcut',
{
'alt': False,
'shift': False,
'control': True,
'ctrl_is_meta': True,
'key': {
'key_code': 76,
'char': 'l'
}
},
category_label=PREF_LABEL_KEYBOARD_SHORTCUTS,
fields=shortcut_fields
)
self.preference.register(
'keyboard_shortcuts',
'comment',
gettext('Toggle comment'),
'keyboardshortcut',
{
'alt': False,
'shift': False,
'control': True,
'ctrl_is_meta': True,
'key': {
'key_code': 191,
'char': '/'
}
},
category_label=PREF_LABEL_KEYBOARD_SHORTCUTS,
fields=shortcut_fields
)
self.preference.register(
'keyboard_shortcuts',
'format_sql',
gettext('Format SQL'),
'keyboardshortcut',
{
'alt': False,
'shift': False,
'control': True,
'ctrl_is_meta': True,
'key': {
'key_code': 75,
'char': 'k'
}
},
category_label=PREF_LABEL_KEYBOARD_SHORTCUTS,
fields=shortcut_fields
)
self.preference.register(
'keyboard_shortcuts',
'auto_complete',
@@ -998,136 +801,6 @@ def register_query_tool_preferences(self):
fields=shortcut_fields
)
self.keyword_case = self.preference.register(
'editor', 'keyword_case',
gettext("Keyword case"), 'radioModern', 'upper',
options=[{'label': UPPER_CASE_STR, 'value': 'upper'},
{'label': LOWER_CASE_STR, 'value': 'lower'},
{'label': PRESERVE_STR, 'value': 'preserve'}],
category_label=PREF_LABEL_SQL_FORMATTING,
help_str=gettext(
'Convert keywords to upper, lower, or preserve casing.'
)
)
self.identifier_case = self.preference.register(
'editor', 'identifier_case',
gettext("Identifier case"), 'radioModern', 'upper',
options=[{'label': UPPER_CASE_STR, 'value': 'upper'},
{'label': LOWER_CASE_STR, 'value': 'lower'},
{'label': PRESERVE_STR, 'value': 'preserve'}],
category_label=PREF_LABEL_SQL_FORMATTING,
help_str=gettext(
'Convert identifiers to upper, lower, or preserve casing.'
)
)
self.function_case = self.preference.register(
'editor', 'function_case',
gettext("Function case"), 'radioModern', 'upper',
options=[{'label': UPPER_CASE_STR, 'value': 'upper'},
{'label': LOWER_CASE_STR, 'value': 'lower'},
{'label': PRESERVE_STR, 'value': 'preserve'}],
category_label=PREF_LABEL_SQL_FORMATTING,
help_str=gettext(
'Convert function names to upper, lower, or preserve casing.'
)
)
self.data_type_case = self.preference.register(
'editor', 'data_type_case',
gettext("Data type case"), 'radioModern', 'upper',
options=[{'label': UPPER_CASE_STR, 'value': 'upper'},
{'label': LOWER_CASE_STR, 'value': 'lower'},
{'label': PRESERVE_STR, 'value': 'preserve'}],
category_label=PREF_LABEL_SQL_FORMATTING,
help_str=gettext(
'Convert data types to upper, lower, or preserve casing.'
)
)
self.spaces_around_operators = self.preference.register(
'editor', 'spaces_around_operators',
gettext("Spaces around operators?"), 'boolean', True,
category_label=PREF_LABEL_SQL_FORMATTING,
help_str=gettext('If set to True, spaces are used around all '
'operators.')
)
self.tab_size = self.preference.register(
'editor', 'tab_size',
gettext("Tab size"), 'integer', 4,
min_val=2,
max_val=8,
category_label=PREF_LABEL_SQL_FORMATTING,
help_str=gettext(
'The number of spaces per tab. Minimum 2, maximum 8.'
)
)
self.use_spaces = self.preference.register(
'editor', 'use_spaces',
gettext("Use spaces?"), 'boolean', False,
category_label=PREF_LABEL_SQL_FORMATTING,
help_str=gettext(
'Specifies whether or not to insert spaces instead of tabs '
'when the tab key or auto-indent are used.'
)
)
self.preference.register(
'Editor', 'indent_new_line',
gettext("Auto-indent new line?"), 'boolean', True,
category_label=PREF_LABEL_EDITOR,
help_str=gettext(
'Specifies whether the newly added line using enter key should '
'be auto-indented or not'
)
)
self.expression_width = self.preference.register(
'editor', 'expression_width',
gettext("Expression Width"), 'integer', 50,
category_label=PREF_LABEL_SQL_FORMATTING,
help_str=gettext(
'maximum number of characters in parenthesized expressions to be '
'kept on single line.'
)
)
self.logical_operator_new_line = self.preference.register(
'editor', 'logical_operator_new_line',
gettext("Logical operator new line"), 'radioModern', 'before',
options=[{'label': gettext('Before'), 'value': 'before'},
{'label': gettext('After'), 'value': 'after'}],
category_label=PREF_LABEL_SQL_FORMATTING,
help_str=gettext(
'Decides newline placement before or after logical operators '
'(AND, OR, XOR).'
)
)
self.lines_between_queries = self.preference.register(
'editor', 'lines_between_queries',
gettext("Lines between queries"), 'integer', 1,
min_val=0,
max_val=5,
category_label=PREF_LABEL_SQL_FORMATTING,
help_str=gettext(
'Decides how many empty lines to leave between SQL statements. '
'If zero it puts no new line.'
)
)
self.new_line_before_semicolon = self.preference.register(
'editor', 'new_line_before_semicolon',
gettext("New line before semicolon?"), 'boolean', False,
category_label=PREF_LABEL_SQL_FORMATTING,
help_str=gettext(
'Whether to place query separator (;) on a separate line.'
)
)
self.row_limit = self.preference.register(
'graph_visualiser', 'row_limit',
gettext("Row Limit"), 'integer',
+1 -1
View File
@@ -90,7 +90,7 @@ class _Preference():
db.session.add(res)
db.session.commit()
res = PrefTable.query.filter_by(
name=name
name=name, cid=cid
).first()
# Save this id for letter use.