translated application menu on macOS

This commit is contained in:
antelle 2021-05-08 10:37:24 +02:00
parent a3174b96d7
commit 60329e086a
No known key found for this signature in database
GPG Key ID: 63C9777AAB7C563C
6 changed files with 105 additions and 19 deletions

View File

@ -4,6 +4,7 @@ import { Locale } from 'util/locale';
import { ThemeWatcher } from 'comp/browser/theme-watcher';
import { AppSettingsModel } from 'models/app-settings-model';
import { Logger } from 'util/logger';
import { Launcher } from 'comp/launcher';
const logger = new Logger('settings-manager');
@ -164,6 +165,20 @@ const SettingsManager = {
Object.assign(Locale, this.neutralLocale, localeValues);
this.activeLocale = loc;
Events.emit('set-locale', loc);
if (Launcher) {
const { ipcRenderer } = Launcher.electron();
const localeValuesForDesktopApp = {};
for (const [key, value] of Object.entries(Locale)) {
if (key.startsWith('sysMenu')) {
localeValuesForDesktopApp[key] = value;
}
}
ipcRenderer.invoke('setLocale', {
locale: loc,
...localeValuesForDesktopApp
});
}
},
getBrowserLocale() {

View File

@ -9,6 +9,8 @@ const electron = require('electron');
const path = require('path');
const fs = require('fs');
const url = require('url');
const { locale, setLocale, getLocaleValues } = require('./scripts/locale');
const { Logger } = require('./scripts/logger');
const { isDev } = require('./scripts/util/app-info');
@ -120,6 +122,10 @@ main.on('ready', () => {
setGlobalShortcuts(appSettings);
subscribePowerEvents();
hookRequestHeaders();
loadLocale().then(() => {
setMenu();
});
})
.catch((e) => {
electron.dialog.showErrorBox('KeeWeb', 'Error loading app: ' + e);
@ -297,9 +303,6 @@ function createMainWindow() {
mainWindow = new electron.BrowserWindow(windowOptions);
logProgress('creating main window');
setMenu();
logProgress('setting menu');
mainWindow.loadURL(htmlPath);
mainWindow.once('ready-to-show', () => {
logProgress('main window ready');
@ -491,34 +494,50 @@ function setMenu() {
{
label: name,
submenu: [
{ role: 'about' },
{ role: 'about', label: locale.sysMenuAboutKeeWeb?.replace('{}', 'KeeWeb') },
{ type: 'separator' },
{ role: 'services', submenu: [] },
{ role: 'services', submenu: [], label: locale.sysMenuServices },
{ type: 'separator' },
{ accelerator: 'Command+H', role: 'hide' },
{ accelerator: 'Command+Shift+H', role: 'hideothers' },
{ role: 'unhide' },
{
accelerator: 'Command+H',
role: 'hide',
label: locale.sysMenuHide?.replace('{}', 'KeeWeb')
},
{
accelerator: 'Command+Shift+H',
role: 'hideothers',
label: locale.sysMenuHideOthers
},
{ role: 'unhide', label: locale.sysMenuUnhide },
{ type: 'separator' },
{ role: 'quit', accelerator: 'Command+Q' }
{
role: 'quit',
accelerator: 'Command+Q',
label: locale.sysMenuQuit?.replace('{}', 'KeeWeb')
}
]
},
{
label: 'Edit',
label: locale.sysMenuEdit || 'Edit',
submenu: [
{ accelerator: 'CmdOrCtrl+Z', role: 'undo' },
{ accelerator: 'Shift+CmdOrCtrl+Z', role: 'redo' },
{ accelerator: 'CmdOrCtrl+Z', role: 'undo', label: locale.sysMenuUndo },
{ accelerator: 'Shift+CmdOrCtrl+Z', role: 'redo', label: locale.sysMenuRedo },
{ type: 'separator' },
{ accelerator: 'CmdOrCtrl+X', role: 'cut' },
{ accelerator: 'CmdOrCtrl+C', role: 'copy' },
{ accelerator: 'CmdOrCtrl+V', role: 'paste' },
{ accelerator: 'CmdOrCtrl+A', role: 'selectall' }
{ accelerator: 'CmdOrCtrl+X', role: 'cut', label: locale.sysMenuCut },
{ accelerator: 'CmdOrCtrl+C', role: 'copy', label: locale.sysMenuCopy },
{ accelerator: 'CmdOrCtrl+V', role: 'paste', label: locale.sysMenuPaste },
{
accelerator: 'CmdOrCtrl+A',
role: 'selectall',
label: locale.sysMenuSelectAll
}
]
},
{
label: 'Window',
label: locale.sysMenuWindow || 'Window',
submenu: [
{ accelerator: 'CmdOrCtrl+M', role: 'minimize' },
{ accelerator: 'Command+W', role: 'close' }
{ accelerator: 'CmdOrCtrl+M', role: 'minimize', label: locale.sysMenuMinimize },
{ accelerator: 'Command+W', role: 'close', label: locale.sysMenuClose }
]
}
];
@ -887,6 +906,23 @@ function saveConfig(name, data, key) {
});
}
function loadLocale() {
return loadConfig('locale').then((localeValues) => {
if (localeValues) {
try {
localeValues = JSON.parse(localeValues);
if (appSettings?.locale === localeValues?.locale) {
setLocale(localeValues);
}
} catch {}
}
locale.on('changed', () => {
setMenu();
saveConfig('locale', JSON.stringify(getLocaleValues()));
});
});
}
// TODO: delete in 2021
function migrateOldConfigs(key) {
const knownConfigs = [

View File

@ -0,0 +1,4 @@
const { ipcMain } = require('electron');
const { setLocale } = require('../locale');
ipcMain.handle('setLocale', (e, values) => setLocale(values));

View File

@ -3,4 +3,5 @@ module.exports.setupIpcHandlers = () => {
require('./ipc-handlers/hardware-crypto');
require('./ipc-handlers/native-module-host-proxy');
require('./ipc-handlers/spawn-process');
require('./ipc-handlers/set-locale');
};

29
desktop/scripts/locale.js Normal file
View File

@ -0,0 +1,29 @@
const { EventEmitter } = require('events');
class Locale extends EventEmitter {}
const locale = new Locale();
let localeValues;
function setLocale(values) {
localeValues = values;
let changed = false;
for (const [key, value] of Object.entries(values)) {
if (locale[key] !== value) {
changed = true;
locale[key] = value;
}
}
if (changed) {
locale.emit('changed');
}
}
function getLocaleValues() {
return localeValues;
}
module.exports = { locale, setLocale, getLocaleValues };

View File

@ -13,6 +13,7 @@ Release notes
`+` displaying the reason why unlock is requested
`+` filters on the auto-type entry selection screen
`+` adding multiple websites to one entry
`+` translated application menu on macOS
`-` fixed a crash after disabling USB devices on Linux
`+` tightened content security policy
`-` KeeWebHttp deprecated