Added zoom scaling options with keyboard shortcuts in runtime. Fixes #6271

This commit is contained in:
Akshay Joshi 2021-03-15 14:17:56 +05:30
parent bf6ee28dae
commit 49a59f8929
12 changed files with 242 additions and 11 deletions

View File

@ -46,12 +46,29 @@ browser and the Python server creating a standalone application.
Runtime Menu
------------
Use the *File Menu* to access the *Runtime Menu*:
.. image:: images/runtime_menu.png
:alt: Runtime Menu
:align: center
Use the *File Menu* to access the *Runtime Menu*:
+-------------------------+---------------------------------------------------------------------------------------------------------+
| Option | Action |
+=========================+=========================================================================================================+
| *Configure...* | Click to open configuration dialog to configure fixed port, port number and connection timeout. |
+-------------------------+---------------------------------------------------------------------------------------------------------+
| *View log...* | Click to open the view log dialog to view the pgAdmin 4 logs. |
+-------------------------+---------------------------------------------------------------------------------------------------------+
| *Enter Full Screen* | Click to enter/exit the full screen mode. Keyboard Shortcuts: OSX (Cmd + Ctrl + F), Other OS (F10). |
+-------------------------+---------------------------------------------------------------------------------------------------------+
| *Actual Size* | Click to change the window size to it original size. Keyboard Shortcuts: OSX (Cmd + 0), |
| | Other OS (Ctrl + 0). |
+-------------------------+---------------------------------------------------------------------------------------------------------+
| *Zoom In* | Click to increase the zoom level. Keyboard Shortcuts: OSX (Cmd + +), Other OS (Ctrl + +). |
+-------------------------+---------------------------------------------------------------------------------------------------------+
| *Zoom Out* | Click to decrease the zoom level. Keyboard Shortcuts: OSX (Cmd + -), Other OS (Ctrl + -). |
+-------------------------+---------------------------------------------------------------------------------------------------------+
Configuration Dialog
--------------------

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 72 KiB

View File

@ -28,6 +28,9 @@ Use the *File* menu to access the following options:
| *Lock Layout* | Click to open a submenu to select the level for locking the UI layout |
| | This can also be changed from browser display :ref:`preferences <preferences>` |
+-------------------------+---------------------------------------------------------------------------------------------------------+
| *Runtime* | Click to open a submenu to Configure, View Log and Zoom settings. Only visible when pgAdmin4 runs in |
| | desktop mode. To know more about runtime menu :ref:`click here <desktop_deployment>` |
+-------------------------+---------------------------------------------------------------------------------------------------------+
The Object Menu
***************

View File

@ -13,6 +13,7 @@ New features
| `Issue #6212 <https://redmine.postgresql.org/issues/6212>`_ - Make the container distribution a multi-arch build with x86_64 and Arm64 support.
| `Issue #6268 <https://redmine.postgresql.org/issues/6268>`_ - Make 'kerberos' an optional feature in the Python wheel, to avoid the need to install MIT Kerberos on the system by default.
| `Issue #6270 <https://redmine.postgresql.org/issues/6270>`_ - Added '--replace' option in Import server to replace the list of servers with the newly imported one.
| `Issue #6271 <https://redmine.postgresql.org/issues/6271>`_ - Added zoom scaling options with keyboard shortcuts in runtime.
Housekeeping
************

View File

@ -13,6 +13,10 @@ const net = require('net');
const {platform, homedir} = require('os');
let pgadminServerProcess = null;
let pgAdminWindowObject = null;
let zoomInShortcut = null;
let zoomOutShortcut = null;
let actualSizeShortcut = null;
let toggleFullScreenShortcut = null;
// This function is used to check whether directory is present or not
// if not present then create it recursively
@ -143,7 +147,7 @@ const getAvailablePort = (fixedPort) => {
const currentTime = (new Date()).getTime();
const serverLogFile = path.join(getLocalAppDataPath(), 'pgadmin4.' + currentTime.toString() + '.log');
const configFileName = path.join(getAppDataPath(), 'runtime_config.json');
const DEFAULT_CONFIG_DATA = {'fixedPort': false, 'portNo': 5050, 'connectionTimeout': 90, 'windowWidth': 1300, 'windowHeight': 900};
const DEFAULT_CONFIG_DATA = {'fixedPort': false, 'portNo': 5050, 'connectionTimeout': 90, 'windowWidth': 1300, 'windowHeight': 900, 'zoomLevel': 0};
// This function is used to read the file and return the content
const readServerLog = () => {
@ -237,6 +241,107 @@ const cleanupAndQuitApp = () => {
}
};
// This function is used to create zoom events based on platform
const setZoomEvents = () => {
if (platform() == 'darwin') {
zoomInShortcut = new nw.Shortcut({key: 'Command+Equal'});
zoomOutShortcut = new nw.Shortcut({key: 'Command+Minus'});
actualSizeShortcut = new nw.Shortcut({key: 'Command+0'});
toggleFullScreenShortcut = new nw.Shortcut({key: 'Command+Ctrl+F'});
} else {
zoomInShortcut = new nw.Shortcut({key: 'Ctrl+Equal'});
zoomOutShortcut = new nw.Shortcut({key: 'Ctrl+Minus'});
actualSizeShortcut = new nw.Shortcut({key: 'Ctrl+0'});
// Use F10 instead of F11. F11 does not work possibly due to Chromium reserving it for their function.
toggleFullScreenShortcut = new nw.Shortcut({key: 'F10'});
}
zoomInShortcut.on('active', function() {
zoomIn();
});
zoomOutShortcut.on('active', function() {
zoomOut();
});
actualSizeShortcut.on('active', function() {
actualSize();
});
toggleFullScreenShortcut.on('active', function() {
toggleFullScreen();
});
zoomInShortcut.on('failed', function(msg) {
let errMsg = 'Failed to register zoom in shortcut with error: ' + msg;
console.warn(errMsg);
});
zoomOutShortcut.on('failed', function(msg) {
let errMsg = 'Failed to register zoom out shortcut with error: ' + msg;
console.warn(errMsg);
});
actualSizeShortcut.on('failed', function(msg) {
let errMsg = 'Failed to register actual size shortcut with error: ' + msg;
console.warn(errMsg);
});
toggleFullScreenShortcut.on('failed', function(msg) {
let errMsg = 'Failed to register toggle full screen shortcut with error: ' + msg;
console.warn(errMsg);
});
};
// This function used to zoom in the pgAdmin window.
const zoomIn = () => {
if (pgAdminWindowObject != null) {
pgAdminWindowObject.zoomLevel += 0.5;
ConfigureStore.set('zoomLevel', pgAdminWindowObject.zoomLevel);
ConfigureStore.saveConfig();
}
};
// This function used to zoom out the pgAdmin window.
const zoomOut = () => {
if (pgAdminWindowObject != null) {
pgAdminWindowObject.zoomLevel -= 0.5;
ConfigureStore.set('zoomLevel', pgAdminWindowObject.zoomLevel);
ConfigureStore.saveConfig();
}
};
// This function used to reset the zoom level of pgAdmin window.
const actualSize = () => {
if (pgAdminWindowObject != null) {
pgAdminWindowObject.zoomLevel = 0;
ConfigureStore.set('zoomLevel', pgAdminWindowObject.zoomLevel);
ConfigureStore.saveConfig();
}
};
const toggleFullScreen = () => {
if (pgAdminWindowObject != null) {
pgAdminWindowObject.toggleFullscreen();
}
};
// This function is used to register zoom events.
const registerZoomEvents = () => {
nw.App.registerGlobalHotKey(zoomInShortcut);
nw.App.registerGlobalHotKey(zoomOutShortcut);
nw.App.registerGlobalHotKey(actualSizeShortcut);
nw.App.registerGlobalHotKey(toggleFullScreenShortcut);
};
// This function is used to unregister zoom events.
const unregisterZoomEvents = () => {
nw.App.unregisterGlobalHotKey(zoomInShortcut);
nw.App.unregisterGlobalHotKey(zoomOutShortcut);
nw.App.unregisterGlobalHotKey(actualSizeShortcut);
nw.App.unregisterGlobalHotKey(toggleFullScreenShortcut);
};
let ConfigureStore = {
fileName: configFileName,
jsonData: {},
@ -312,5 +417,12 @@ module.exports = {
getServerLogFile: getServerLogFile,
getRunTimeConfigFile: getRunTimeConfigFile,
setPgAdminWindowObject: setPgAdminWindowObject,
zoomIn: zoomIn,
zoomOut: zoomOut,
actualSize: actualSize,
toggleFullScreen: toggleFullScreen,
setZoomEvents: setZoomEvents,
registerZoomEvents: registerZoomEvents,
unregisterZoomEvents: unregisterZoomEvents,
ConfigureStore: ConfigureStore,
};

View File

@ -118,6 +118,14 @@ function startDesktopMode() {
'focus': true,
'show': true,
});
} else if (chunk.indexOf('Runtime Zoom In') > -1) {
misc.zoomIn();
} else if (chunk.indexOf('Runtime Zoom Out') > -1) {
misc.zoomOut();
} else if (chunk.indexOf('Runtime Actual Size') > -1) {
misc.actualSize();
} else if (chunk.indexOf('Runtime Toggle Full Screen') > -1) {
misc.toggleFullScreen();
} else {
misc.writeServerLog(chunk);
}
@ -209,6 +217,12 @@ function launchPgAdminWindow() {
// Set pgAdmin4 Windows Object
misc.setPgAdminWindowObject(pgadminWindow);
// Set the zoom level stored in the config file.
pgadminWindow.zoomLevel = misc.ConfigureStore.get('zoomLevel', 0);
// Set zoom in and out events.
misc.setZoomEvents();
pgadminWindow.on('closed', function() {
misc.cleanupAndQuitApp();
});
@ -252,9 +266,20 @@ function launchPgAdminWindow() {
});
});
misc.ConfigureStore.set('windowWidth', width);
misc.ConfigureStore.set('windowHeight', height);
misc.ConfigureStore.saveConfig();
// No need to write setting in case of full screen
if (!pgadminWindow.isFullscreen) {
misc.ConfigureStore.set('windowWidth', width);
misc.ConfigureStore.set('windowHeight', height);
misc.ConfigureStore.saveConfig();
}
});
pgadminWindow.on('blur', function() {
misc.unregisterZoomEvents();
});
pgadminWindow.on('focus', function() {
misc.registerZoomEvents();
});
});
}

View File

@ -10,6 +10,7 @@
import json
import logging
import os
import sys
from abc import ABCMeta, abstractmethod, abstractproperty
from smtplib import SMTPConnectError, SMTPResponseException, \
SMTPServerDisconnected, SMTPDataError, SMTPHeloError, SMTPException, \
@ -55,7 +56,6 @@ try:
from flask_security.views import default_render_json
except ImportError as e:
# Support Flask-Security-Too == 3.2
import sys
if sys.version_info < (3, 8):
from flask_security.views import _render_json as default_render_json
@ -272,6 +272,17 @@ class BrowserModule(PgAdminModule):
# We need 'Configure...' and 'View log...' Menu only in runtime.
if current_app.PGADMIN_RUNTIME:
full_screen_label = gettext('Enter Full Screen (F10)')
actual_size_label = gettext('Actual Size (Ctrl 0)')
zoom_in_label = gettext('Zoom In (Ctrl +)')
zoom_out_label = gettext('Zoom Out (Ctrl -)')
if sys.platform == 'darwin':
full_screen_label = gettext('Enter Full Screen (Cmd Ctrl F)')
actual_size_label = gettext('Actual Size (Cmd 0)')
zoom_in_label = gettext('Zoom In (Cmd +)')
zoom_out_label = gettext('Zoom Out (Cmd -)')
menus['file_items'].append(
MenuItem(
name='mnu_runtime',
@ -289,7 +300,32 @@ class BrowserModule(PgAdminModule):
module=PGADMIN_BROWSER,
callback='mnu_viewlog_runtime',
priority=1,
label=gettext('View log...')
label=gettext('View log...'),
below=True,
), MenuItem(
name='mnu_toggle_fullscreen_runtime',
module=PGADMIN_BROWSER,
callback='mnu_toggle_fullscreen_runtime',
priority=2,
label=full_screen_label
), MenuItem(
name='mnu_actual_size_runtime',
module=PGADMIN_BROWSER,
callback='mnu_actual_size_runtime',
priority=3,
label=actual_size_label
), MenuItem(
name='mnu_zoomin_runtime',
module=PGADMIN_BROWSER,
callback='mnu_zoomin_runtime',
priority=4,
label=zoom_in_label
), MenuItem(
name='mnu_zoomout_runtime',
module=PGADMIN_BROWSER,
callback='mnu_zoomout_runtime',
priority=5,
label=zoom_out_label
)]
)
)

View File

@ -836,7 +836,7 @@ define('pgadmin.browser', [
enable: (_m.enable == '' ? true : (_.isString(_m.enable) &&
_m.enable.toLowerCase() == 'false') ?
false : _m.enable),
node: _m.node, checked: _m.checked,
node: _m.node, checked: _m.checked, below: _m.below,
});
};

View File

@ -19,7 +19,7 @@ define([
var menu_opts = [
'name', 'label', 'priority', 'module', 'callback', 'data', 'enable',
'category', 'target', 'url' /* Do not show icon in the menus, 'icon' */ , 'node',
'checked', 'menu_items',
'checked', 'below', 'menu_items',
],
defaults = {
url: '#',
@ -101,7 +101,14 @@ define([
url.append(textSpan);
this.$el = $('<li/>').append(url);
var mnu_element = $('<li/>').append(url);
// Check if below parameter is defined and true then we need to add
// separator.
if (!_.isUndefined(this.below) && this.below === true) {
mnu_element.append('<li class="dropdown-divider"></li>');
}
this.$el = mnu_element;
}
},

View File

@ -39,6 +39,34 @@ _.extend(pgBrowser, {
mnu_viewlog_runtime: function() {
this.send_signal_to_runtime('Runtime Open View Log');
},
// This function is callback function when 'Enter Full Screen' menu is clicked.
mnu_toggle_fullscreen_runtime: function() {
var menu_label = document.querySelector('#mnu_toggle_fullscreen_runtime span').innerHTML;
if (menu_label.indexOf('Enter Full Screen') > 0) {
document.querySelector('#mnu_toggle_fullscreen_runtime span').innerHTML = menu_label.replace('Enter', 'Exit');
} else if (menu_label.indexOf('Exit Full Screen') > 0) {
document.querySelector('#mnu_toggle_fullscreen_runtime span').innerHTML = menu_label.replace('Exit', 'Enter');
}
this.send_signal_to_runtime('Runtime Toggle Full Screen');
},
// This function is callback function when 'Actual Size' menu is clicked.
mnu_actual_size_runtime: function() {
this.send_signal_to_runtime('Runtime Actual Size');
},
// This function is callback function when 'Zoom In' menu is clicked.
mnu_zoomin_runtime: function() {
this.send_signal_to_runtime('Runtime Zoom In');
},
// This function is callback function when 'Zoom Out' menu is clicked.
mnu_zoomout_runtime: function() {
this.send_signal_to_runtime('Runtime Zoom Out');
}
});
export {pgBrowser};

View File

@ -22,6 +22,8 @@
enable: "{{ item.enable }}",
{% if item.checked is defined %}checked: {% if item.checked %}true{% else %}false{% endif %},
{% endif %}
{% if item.below is defined %}below: {% if item.below %}true{% else %}false{% endif %},
{% endif %}
{% if item.menu_items %}menu_items: {{MENU_ITEMS(key, item.menu_items)}}
{% endif %}
}